EF6和多种配置(SQL Server和SQL Server Compact)

更新:问题已解决,请参阅此问题的结尾。

问题

我们尝试在一个场景中使用Entity Framework 6和基于代码的配置,我们在同一AppDomain同时使用SQL Server和SQL Server CE。

这个非常简单的场景似乎不是“按设计”支持的。 来自EF团队:

注意:我们不支持在同一AppDomain中使用多个配置类。 如果使用此属性为两个上下文设置不同的配置类,则会引发exception。

更多信息: 基于代码的配置(Codeplex)

问题是

我们如何从这里前进? 任何帮助将不胜感激! 是否有更灵活的方法将配置连接到上下文而不是AppDomain

(我们的上下文类位于不同的程序DbConfigurationType 。我们尝试过DbConfigurationType属性,但问题是EF本身)

配置文件:

正常SQL服务器的配置

 public class EfConfiguration : DbConfiguration { public EfConfiguration() { SetProviderServices( SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance); SetDefaultConnectionFactory(new SqlConnectionFactory()); } } 

SQL Server Compact Edition的配置

 public class EfCeConfiguration : DbConfiguration { public EfCeConfiguration() { SetProviderServices( SqlCeProviderServices.ProviderInvariantName, SqlCeProviderServices.Instance); SetDefaultConnectionFactory( new SqlCeConnectionFactory(SqlCeProviderServices.ProviderInvariantName)); } } 

更新:

我们得到的错误是:

System.TypeInitializationException:’MyProject.Repositories.Base.DataContext’的类型初始值设定项引发了exception。 —-> System.InvalidOperationException:设置了’EfCeConfiguration’的实例,但是在与’DataContext’上下文相同的程序集中未发现此类型。 将DbConfiguration类型放在与DbContext类型相同的程序集中,在DbContext类型上使用DbConfigurationTypeAttribute指定DbConfiguration类型,或在配置文件中设置DbConfiguration类型。 有关详细信息,请参阅http://go.microsoft.com/fwlink/?LinkId=260883 。

更新2,解决方案如上所述,我们只能有一个配置。 这是一个问题,因为Sql和SqlCe使用不同的提供程序。 如果我们使用“SetDefaultConnectionFactory”来适应一种类型的数据库,那么另一种将失败。

而是将连接提供到上下文中,如下面标记为答案的post中所述。 一旦你总是用连接初始化上下文而不是连接字符串,你就可以了。 您可以从配置中删除SetDefaultConnectionFactory调用。 我们仅使用以下代码来配置SqlCe Context,而不使用Sql Context的配置。

  public class CommonEfConfiguration : DbConfiguration { public CommonEfConfiguration() { // EF does not know if the ce provider by default, // therefore it is required to be informed about it. // The connection factories are not necessary since the connection // is always created in the UnitOfWork classes SetProviderServices(SqlCeProviderServices.ProviderInvariantName, SqlCeProviderServices.Instance); } } 

编辑:基于错误的详细信息:您是否已经尝试告诉EF在哪里找到配置类?

 [DbConfigurationType("MyNamespace.MyDbConfiguration, MyAssemblyFullyQualifiedName")] public class MyContextContext : DbContext { } 

如果那不能成功,那么请看替代方案

将Context与构造函数DbConnection一起使用

 public class MYDbContext : DbContext { // MIgration parameterless constructor is managed in MyMigrationsContextFactory public MyDbContext(string connectionName) : base(connectionName) { } // no this public MYDbContext(DbConnection dbConnection, bool contextOwnsConnection) // THIS ONE : base(dbConnection, contextOwnsConnection) { } 

然后,您需要为每个提供商提供“DBConnection”连接。 对于SQL服务器

  public DbConnection GetSqlConn4DbName(string dataSource, string dbName) { var sqlConnStringBuilder = new SqlConnectionStringBuilder(); sqlConnStringBuilder.DataSource = String.IsNullOrEmpty(dataSource) ? DefaultDataSource : dataSource; sqlConnStringBuilder.IntegratedSecurity = true; sqlConnStringBuilder.MultipleActiveResultSets = true; var sqlConnFact = new SqlConnectionFactory(sqlConnStringBuilder.ConnectionString); var sqlConn = sqlConnFact.CreateConnection(dbName); return sqlConn; } 

对于SqlCe工厂重复,它还可以生成DBConnection SqlCe连接因子创建连接

我做了什么:

 public partial class MyDataBaseContext : DbContext { public MyDataBaseContext (string ConnectionString) : base(ConnectionString) { } } 

我在微软论坛post的post中找到了解决方案。

基本上,我有两个项目,每个项目都有自己的上下文。 entity framework只加载(第一个)DbConfiguration类之一,并尝试对两个项目使用相同的配置。 这就是出现错误消息的原因

“已设置’EfCeConfiguration’的实例,但未在与’DataContext’上下文相同的程序集中发现此类型”。

因此,正如有人在Microsoft论坛post中建议的那样 ,我从两个项目中inheritance自DbContext的类中删除了所有[DbConfigurationType(typeof(DbConfigurationClass))] anotations,并且错误不再发生。