Skip to main content
All docs
V21.2

DevExpress v24.1 Update — Your Feedback Matters

Our What's New in v24.1 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

How to: Use Both Entity Framework 6 and XPO in a Single Application

  • 5 minutes to read

This topic demonstrates how to create a simple XAF application that uses both the Entity Framework 6 (EF 6) and eXpress Persistent Objects (XPO) business models. For instance, this approach is required if you want to reuse the Entity Framework 6 model from a non-XAF application in your existing XPO-based XAF project. As a result, your application will access two databases, the first one using XPO and the second using EF 6.

Note

The Solution Wizard generates the code shown in this help topic when you create an application. Follow this article if you want to implement the demonstrated functionality in an existing XAF solution. You can choose both EF 6 and XPO in the Choose ORM page of the wizard (Entity Framework 6 plus eXpress Persistent Objects).

In ASP.NET Core Blazor applications, you cannot use the EF 6 data model - use EF Core instead. When you create a new application, the Solution Wizard allows you to choose the XPO or EF Core data model.

#Add an EF 6 Data Model in Code

  • Reference the EntityFramework.dll and EntityFramework.SqlServer.dll assemblies. You can use NuGet to download and reference these assemblies automatically (see Get Entity Framework). The supported Entity Framework version is 6.
  • Reference the DevExpress.ExpressApp.EF6.v21.2.dll assembly, which provides Entity Framework 6 support in XAF.
  • In the module project, implement the following EntityFrameworkSampleObject and MyDbContext classes (learn more about Entity Framework 6 Code First in XAF).

    using System.ComponentModel;
    using EntityFramework;
    using DevExpress.Persistent.Base;
    using DevExpress.ExpressApp.DC;
    // ...
    [DefaultClassOptions]
    public class EntityFrameworkSampleObject {
        [Browsable(false)]
        public int Id { get; protected set; }
        public string Name { get; set; }
        [FieldSize(FieldSizeAttribute.Unlimited)]
        public String Description { get; set; }
    }
    public class MyDbContext : DbContext {
        public MyDbContext(string connectionString) : base(connectionString) { }
        public DbSet<EntityFrameworkSampleObject> SampleObjects { get; set; }
    }
    

#Add an XPO Data Model in Code

In the module project, implement the following BaseObject descendant.

using DevExpress.Xpo;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.ExpressApp.DC;
// ...
[DefaultClassOptions]
public class XpoSampleObject : BaseObject {
    public XpoSampleObject(Session session) : base(session) { }
    private string name;
    public string Name {
        get { return name; }
        set { SetPropertyValue(nameof(Name), ref name, value); }
    }
    private string description;
    [Size(SizeAttribute.Unlimited)]
    public String Description { 
        get {return description; }
        set { SetPropertyValue(nameof(Description), ref description, value); }
    }
}

#Populate the DefaultObjectSpaceProviders Collection

By default, the CreateDefaultObjectSpaceProvider method implemented in the WinApplication.cs (WinApplication.vb) and WebApplication.cs (WebApplication.vb) files assigns an XPObjectSpaceProvider instance to the ObjectSpaceProvider parameter. Instead, you can add multiple Object Space Providers to the ObjectSpaceProviders parameter. XAF will automatically determine what Object Space Provider should be used to create an Object Space for each particular business object type. Modify the default implementation of the CreateDefaultObjectSpaceProvider method for both Windows Forms and ASP.NET Web Forms application projects in the following manner.

using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.EF;
// ...
protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) {
    args.ObjectSpaceProviders.Add(
        new XPObjectSpaceProvider(ConfigurationManager.ConnectionStrings["ConnectionStringXpo"].ConnectionString, null));
    args.ObjectSpaceProviders.Add(
        new EFObjectSpaceProvider(typeof(MyDbContext),
        ConfigurationManager.ConnectionStrings["ConnectionStringEF"].ConnectionString));
}

XAF uses the first registered Object Space Provider for the following purposes:

Ensure that NonPersistentObjectSpaceProvider is not the first registered Provider in your application.

#Specify Connection Strings for EF 6 and XPO

The code in the previous section reads connection strings for each Object Space Provider from the configuration file (App.config in a Windows Forms application project and Web.config in ASP.NET Web Forms), so specify the ConnectionStringXpo and ConnectionStringEF connection strings in both files.

<connectionStrings>
    <add name="ConnectionStringXpo" connectionString="Integrated Security=SSPI;
    Pooling=false;Data Source=(local);Initial Catalog=MultipleORMsExampleXpo" />
    <add name="ConnectionStringEF" connectionString="Integrated Security=SSPI;
    Data Source=(local);Initial Catalog=MultipleORMsExampleEF" />
</connectionStrings>

#Run the Application

Now you can run the application (Windows Forms or ASP.NET Web Forms) to see that both EF 6 and XPO objects are accessible.

EFXPO

Tip

If you want to create an Object Space in code when several Object Space providers are registered, use the overload of XafApplication.CreateObjectSpace method that takes the objectType parameter. In this instance, an Object Space that supports a particular object type will be created.

Note

When multiple Object Space Providers are registered in the XafApplication.ObjectSpaceProviders property, the ModuleUpdater.UpdateDatabaseAfterUpdateSchema method is executed multiple times, once for each registered Provider. In this method, before accessing an object of a particular type, check if the current Object Space supports this type using the IObjectSpace.CanInstantiate method.

See Also