April 2011 - Posts

XPO - A simple benchmark against EF 6 and EF Core

We recently published a BenchmarkDotNet-based benchmark on GitHub: https://github.com/DevExpress/XpoNetCoreDemos/tree/master/ORMBenchmark.

We used it to test the performance of the following Object-Relational Mapping (ORM) libraries for .NET Framework 4.6.1 and higher:

You can run the benchmark tests or review our results here. Needless to say, the lower the execution time the better. Example:

All benchmarks were executed using .NET 4.6.1, AnyCPU release builds (include warm-up), Windows 10 Enterprise x64, local Microsoft SQL Server 2016 Developer Edition, i7-7700 CPU @3.6GHz / 16GB RAM / SSD. Please note that DevExpress.Xpo and other referenced libraries will automatically be restored from Nuget. Edit the connection string in the App.config file, update the ORM library and target framework versions, if necessary. 

Your feedback is needed!

We kept the first version of this test as simple as possible.  Feel free to make data model and test case modifications to cover additional usage scenarios. For instance,  measure memory consumption, include scenarios with BLOBs, reference and collection properties, etc. We'd love to hear your feedback about this project. Drop us a line below, thanks.

See Also

XPO ORM Library – Available Free-of-Charge in v18.1!

Love XPO and want to help us promote it? Add the package through Nuget.org instead of DevExpress Nuget!

XPO - Miscellaneous Updates (v18.1)

In this blog post, I will cover a few XPO features that should simplify your development process.

XPO is available through Nuget.org

https://www.nuget.org/packages/DevExpress.Xpo/ - it is now there for anyone to use, free-of-charge.

We are a bit late with this announcement - a third-party reserved the XPO name in the past. So, skip the stats for versions earlier 18.1.3.

BTW, to avoid long legal proceedings with Nuget packages, consider Nuget's Package ID prefix reservation feature. We will be using it from now on;).

Nullable columns

Our core APIs now include properties that allow columns to accept Null values:

You can also use the ColumnDefaultValue, ColumnDbDefaultValue, Nullable, NullableBehavior attributes and specify the required behavior declaratively.

Refer to the following topics to learn more:

For the best experience, we recommend that you install these hot fixes:

  • T638325 - InvalidCastException is thrown when updating the database schema if a default column value is invalid;
  • T642096 - FormatException ("String was not recognized as a valid DateTime") occurs when a nullable datetime column uses an empty string as a default value.

Template Gallery integration

With this release, XPO item and project templates are available through the DevExpress Template Gallery. Select a required platform and look for the XPO group:

Previously, these items were available through the "Add New Item" and "Add New Project" dialogs only.

XPO + .NET Core DB Provider for SAP ASE = LOVE

If you would like to implement a custom XPO connection provider for AdoNetCore.AseClient, please refer to our published example on GitHub. This is another good example of XPO extensibility. 

Currently, XPO for .NET Core / .NET Standard 2.0 officially supports SQL Server, MySql, PostgreSQL, FireBird, SQLite and Oracle for .NET Core. As we noted in our introductory post, the lack of support for other providers is not a limitation of XPO - only a function of support from RDBMS vendors. Once these RDBMS vendors support .NET Standard 2.0, we will test XPO against these backend providers and will add them to our supported list once our internal qualification requirements have been met.

Your feedback is needed!

Which features did you like? Please let our team know in comments.

Love XPO and want to help us promote it? Add the package through Nuget.org instead of DevExpress Nuget!

  Yekaterina K.
  Technical writer
  XPO team

XPO ORM Library – Available Free-of-Charge in v18.1!

Available Free-of-Charge without Technical Support
For 15 years, XPO (the DevExpress ORM library for .NET) has been bundled in all of our product subscriptions. With our most recent release, we’re making XPO available free-of-charge. If you’re not familiar with XPO, you can learn more about its feature set here. If you’ve used XPO in the past or are familiar with capabilities, you can read what’s new in v18.1 here.

If you are interested in XPO and want to receive technical support (to reiterate, tech support is not available when using the free version), you can purchase the XPO - ORM Library Subscription for $399.99. Full terms of use can be found here.

XPO continues to be bundled with all other DevExpress Subscriptions. If you own an active Subscription (Universal, DXperience, WinForms, WPF, ASP.NET, Reporting, DevExtreme), you are already licensed to use XPO (with tech support).

Frequently Asked Questions
Q: What platforms and technologies does XPO support? 
A: XPO helps access and manipulate data stored in-memory or within traditional database engines (RDBMS) running on Windows, MacOS or Linux (in desktop, web and mobile projects powered by .NET). Technically, you can create Console, WinForms, WPF, UWP, Xamarin, ASP.NET WebForms and ASP.NET Core apps with XPO. New .NET Standard-based technologies like Blazor will be supported in the future as well (see my recent example).

Q: Has anything changed for existing subscribers?
ANothing has changed for those with active subscriptions to DevExpress Universal, DXperience, WinForms, ASP.NET, WPF, and DevExpress Reports. If you own an active DevExtreme subscription, we've officially added XPO to its product list and we'll happily provide tech support free-of-charge as long as your subscription remains active.

Q: How can I obtain XPO assemblies for my apps?
A: You have two options: You can either use our Unified Installer or Nuget. Nuget is quick and easy but does not come with Visual Studio design time support. Nuget feed: https://www.nuget.org/packages/DevExpress.Xpo/.
If you'd like to install XPO via our Unified Installer, simply download our trial installation and install our products in "trial mode." XPO will be automatically installed without trial restrictions. If you own a subscription, you can use your existing DevExpress credentials when prompted by our Unified Installer. DevExtreme subscribers require one additional step - see the "Known/expected behavior" section below. Refer to https://www.devexpress.com/Support/EULAs/xpo.xml for a complete list of redistributable assemblies and our terms of use. 

Q: Why is XPO unavailable through the public feed at Nuget.org?
A: This was and is our goal too, but our name was reserved by a third-party in the past without permission. The third-party package is currently unlisted by the author due to compliance issues. If the Nuget.org administration allows us to use our name, we will certainly upload XPO there as well.
UPDATE: XPO is now available through Nuget.org: https://www.nuget.org/packages/DevExpress.Xpo/. Use it instead of the DevExpress Nuget feed: https://nuget.devexpress.com/free/api.

Q: Is XPO's source code also free for everyone?
A: No. It's available for Universal and DXperience subscribers only. 

Q: I want to use your ORM, but I don't own a paid subscription (thus, I have no access to support services). How should I get started on my own if using the free version? 
A: You can search our online documentation and our support database (with many KB and Code Examples) as needed.

Known/expected behavior
1. Personal DevExpress Nuget feed (with an authorization key) for DevExtreme subscribers does not contain the DevExpress.Xpo package. 
Solution: Use the public feed: https://www.nuget.org/packages/DevExpress.Xpo/.
UPDATE: The DevExpress.Xpo package is now available for DevExtreme subscribers via their personal DevExpress Nuget feed as well.

2. Unified installer does not automatically install XPO for DevExtreme subscribers. Separate DevExtreme installer does not contain XPO at all. 
Solution: If you don't need XPO design-time features, use the public feed: https://www.nuget.org/packages/DevExpress.Xpo/. Otherwise, use the unified installer and select "WebForms, MVC, Bootstrap or Core" or other .NET-based products on the "Select the products you'd like to install" screen. This was done intentionally so as not to overwhelm DevExtreme users who are not interested in XPO with unnecessary installations steps or to overly complicate installation logic.

3. T636985: Data Model Designer - Trial Version dialog may pop up for licensed owners of "XPO - ORM Library Subscription", DevExtreme, WPF, ASP.NET, Reporting (Fixed in v18.1.4). 
Solution: Safely skip or wait for a hot fix build.
UPDATE:  Download a hot fix build or install v18.1.4+.

Love XPO and want to help us promote it? Add the package through Nuget.org instead of DevExpress Nuget!

XPO - .NET Core Enhancements (v18.1)

Extended database support
With our upcoming release (v18.1), XPO for .NET Core / .NET Standard 2.0 will support the Oracle Data Provider 12.2 for .NET Core in addition to SQL Server, MySql, PostgreSQL, FireBird and SQLite. As we noted in our introductory post, the lack of support for other providers is not a limitation of XPO - only a function of support from RDBMS vendors. Once these RDBMS vendors support .NET Standard 2.0, we will test XPO against these backend providers and will add them to our supported list once our internal qualification requirements have been met. See Also: How to implement a custom XPO connection provider for AdoNetCore.AseClient.

XPO Profiler supports ASP.NET Core projects
As some of you already know, XPO Profiler is a tool designed to discover performance bottlenecks and code issues. Profiling logs include SQL queries, session method calls, query duration, passed parameters, and callstacks. To enable performance profiling in your ASP.NET Core projects, you'll need to add a special API Controller:

using Microsoft.AspNetCore.Mvc;
using DevExpress.Xpo.Logger;

namespace DevExpress.Xpo.AspNetCoreMvcDemo.Controllers {
    public class XpoLoggerController : Controller {
        readonly static LoggerBase logger = new LoggerBase(50000);
        static XpoLoggerController() {
        public LogMessage[] GetCompleteLog() {
            return logger.GetCompleteLog();
        public LogMessage GetMessage() {
            return logger.GetMessage();
        public LogMessage[] GetMessages(int messagesAmount) {
            return logger.GetMessages(messagesAmount);
Complete documentation will ship with our official v18.1 release:  Connect the XPO Profiler to an ASP.NET Core Application. In the meantime, you can use our GitHub demo with the current beta.

Dependency Injection for ASP.NET Core projects
We've implemented new extension methods for the standard IServiceCollection interface to register useful XPO services for the ASP.NET Core pipeline. This follows best practices for the platform and allows you to automatically manage XPO’s data layer and session life cycle as needed.

To call these extensions, the Microsoft.Extensions.DependencyInjection namespace must be imported. Here is an example of the modified ConfigureServices method in the Startup class inside an ASP.NET Core project:

        public void ConfigureServices(IServiceCollection services) {
            services.AddXpoDefaultUnitOfWork(true, options =>
                    .UseEntityTypes(new Type[] { typeof(User) })

You can access  or resolve the UnitOfWork service in your Controllers (example), Views markup or Startup (example) class using standard ASP.NET Core techniques. For more information, refer to the Dependency injection in ASP.NET CoreDependency injection into controllers in ASP.NET Core and Dependency injection into views in ASP.NET Core articles in Microsoft documentation.  Additional XPO examples will be available with the official release at ASP.NET Core Dependency Injection in XPO.

BONUS: I also have an XPO .NET Core version up and running with the Mono runtime on WebAssembly in a Blazor app for both standalone and ASP.NET Core hosted deployment. The example below was used for the in-memory data store within a web browser:

            var serviceProvider = new BrowserServiceProvider(services => {
                services.AddXpoDefaultUnitOfWork(true, options =>
                    .UseEntityTypes(new Type[] { typeof(WeatherForecast) })

NOTE: we do not officially support WebAssembly-based .NET runtimes at this stage (and of course, Blazor is currently an experimental project). I did this test just for fun and research purposes.  Are you also interested in testing XPO with Blazor? Leave a comment to this post and I will email you my working XPO sample.

Love XPO and want to help us promote it? Add the package through Nuget.org instead of DevExpress Nuget!

XPO - Firebird 3.0 Server and other new DB feature Support

Extended database support

As you may already know, XPO (our object-relational mapping library) supports more than a dozen database engines (including SQL Server, Oracle and various Open Source products). As part of our ongoing commitment to support the needs of those using XPO, we've updated it with the following database specific features:


In addition to SQL Server, MySql, PostgreSQL and SQLite, XPO for .NET Core / .NET Standard 2.0 supports ADO.NET provider 5.11+ for Firebird starting with v17.2.5. As we noted in our introductory post, the lack of support for other providers is not an XPO limitation - as soon as RDBMS vendors begin supporting .NET Standard 2.0, we will test XPO with these RDBMS providers and add them to our supported list.

Support for Firebird 3.0 server and the client ADO.NET data provider (FirebirdSql.Data.FirebirdClient 5.8.0) will be available in v18.1. We will also support the Substring criteria function that was missing before.


XPO currently supports Npgsql versions up to v2.0.11, and the runtime System.Guid type maps to the CHAR(36) column. The Npgsql library supports the UUID column type, a more natural solution for a primary key, starting with v3.1.0. XPO support for this latest Npgsql version and its features is available in v18.1. If you do not want to migrate your existing database, set the static PostgreSqlConnectionProvider.GlobalUseLegacyGuidSupport flag to True to inform XPO that System.Guid properties should be mapped to CHAR(36) as before.

SQL Server

Support for the Row Level Security and Dynamic Data Masking feature of MS SQL Server 2016 and SQL Azure is available starting with v17.2.3.


Support for Oracle 12c (both 12.1 and 12.2) version is available starting with v17.2.3.

SQL Anywhere

We have added support for fetching of table lists from the ASA database in v18.1 (it requires special privileges for the query). This was helpful for a specific Report Server scenario. Did you know that various DevExpress products besides XAF use XPO core features for data access?

WCF Data Services & OData v4 client

The IsOutlookIntervalToday and a dozen or so other IsOutlookXXX criteria functions work with grid data sources for Server and Instant Feedback Modes starting with v17.2.3. These are the WcfInstantFeedbackSource / WcfServerModeSource and ODataServerModeSource / ODataInstantFeedbackSource components from the DevExpress Data library.

Your feedback counts

What do you think of the features above? Have you built XPO apps on the .NET Core platform so far? As always, we will be more than happy to provide v18.1 early access preview builds to users who want to ensure that we have covered their needs in the best possible way. Contact me at dennis@devexpress.com or use the https://www.devexpress.com/ask service.

Guess the next XPO feature!

We are finishing work on a cool and popular user request for v18.1. If you are an XPO fan like me, can you guess its name? Tip: the name contains 'NULL'. I am looking forward to hearing from you in comments!

Love XPO and want to help us promote it? Add the package through Nuget.org instead of DevExpress Nuget!

More Posts