配置多个数据库Entity Framework 6

33

在我的解决方案中,我有两个使用Entity Framework 6的项目。每个项目指向不同的数据库,但都使用相同的数据提供程序——SQL Server。 我的解决方案中的第三个项目需要同时使用这两个数据库。我的问题是如何配置这些上下文。我尝试创建一个独立程序集中的配置类:

namespace OSAD_Base
{
    class EfDbConfiguration : DbConfiguration
    {
        public EfDbConfiguration()
        {
            SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance);
        }
    }
}

并在每个上下文类中引用此配置:

namespace IntegrationDb
{
    [DbConfigurationType("OSAD_Base.EfDbConfiguration, OSAD_Base")]
    public partial class IntegrationEntities : DbContext
    {
        public IntegrationEntities(string connectionString)
            : base(connectionString)
        {
        }
    }
}

当我初始化我的第一个context时,一切正常,但是当第二个context初始化(顺序无关紧要)时,我会遇到以下错误:

已设置“EfDbConfiguration”的实例,但是该类型未在与“B1Entities”context相同的程序集中发现。将DbConfiguration类型放置在与DbContext类型相同的程序集中,使用DbContext类型上的DbConfigurationTypeAttribute指定DbConfiguration类型,或在配置文件中设置DbConfiguration类型。有关详细信息,请参见http://go.microsoft.com/fwlink/?LinkId=260883

我还尝试在我的app.config(启动项目的配置文件)中创建一个entityframework部分,但是得到以下错误:

配置系统初始化失败

无法识别的配置节entityFramework

如何在同一个解决方案中使用2个单独的EF项目?


可能重复的问题 https://dev59.com/fXM_5IYBdhLWcg3wt1rD - Jitendra Pancholi
3个回答

31

在Entity Framework 6中,你有多少个DbContext并不重要。只需要将连接字符串放入启动项目的appConfig或webConfig文件中即可。

然后你就可以开始使用了。

以下是具有两个连接字符串的appConfig示例,分别为Ef 6.01和Sql Compact 4.0。

<configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="MainDb" connectionString="Data Source=|DataDirectory|\Db.sdf" providerName="System.Data.SqlServerCe.4.0" />
    <add name="AnotherDb" connectionString="Data Source=|DataDirectory|\AnotherDb.sdf" providerName="System.Data.SqlServerCe.4.0" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlCeConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="System.Data.SqlServerCe.4.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlServerCe.4.0" type="System.Data.Entity.SqlServerCompact.SqlCeProviderServices, EntityFramework.SqlServerCompact" />
    </providers>
  </entityFramework>

DbContexts的示例:

public class AppDb : DbContext
{
    public AppDb()
        : base("MainDb")
    {

    }
}

public class AnotherDb : DbContext
{
    public AnotherDb()
        : base("AnotherDb")
    {

    }
}

你的项目是否分开并不重要,唯一重要的是启动项目的配置。

如果您需要其他信息,请告诉我。

祝好运


我在连接字符串方面没有问题。这个工作正常。问题是要为上下文定义提供程序。试图将实体框架添加到启动项目的app.config中会导致错误,因为实体框架甚至都没有被引用。添加以下标记: - Motty
请查看我上面的帖子。 - Motty
它与AppDb和AnotherDb是同一提供程序,但两个或多个提供程序有多个配置类。在“移动DbConfiguration”部分下解释是不可能的。http://msdn.microsoft.com/en-us/data/jj680699.aspx有些情况下,无法将DbConfiguration类放置在与DbContext类相同的程序集中。 - Kim Ki Won
16
完全没有回答问题。 - Kugel
2
这个答案对我来说很满意,因此这个答案对我来说完全可以。 - Tom Stickel
1
@Kugel问题:两个不同项目中的两个db上下文。我该如何配置它们的连接?答案:无论你有多少项目和这些类在哪里,都没有关系。只需在启动项目的app.config或web.config中定义2个连接字符串,并在db上下文类中使用连接字符串名称。您可以为每个db上下文使用相同或不同的数据库,甚至可以使用不同的数据库引擎。那么,你怎么能说它根本没有回答问题呢? - Yaser Moradi

10

EntityFramework 6的连接字符串应该放在配置文件中,该文件位于执行文件夹中(警告!)。 例如,如果OP在解决方案中有多个项目,则连接字符串必须在属于主执行项目的配置文件中。

现在,如果您想在代码中定义连接字符串,可以在配置文件中创建虚拟连接字符串,并为实体的实例提供新的连接字符串:

DBEntities e = new DBEntities();
e.Database.Connection.ConnectionString = "Data Source=MyServ;Initial Catalog=MyDB;Persist Security Info=True;User ID=sa;Password=***;Application Name=MyApp";

0

下面是我在使用EF6处理两个数据库时所做的:

Web.config

      <connectionStrings>
        <add name="EntityContainer" connectionString="metadata=res://WebService/Database.Database.csdl|res://WebService/Database.Database.ssdl|res://WebService/Database.Database.msl; .../>
        <add name="ArchiveEntityContainer" connectionString="metadata=res://WebService/Database.Database.csdl|res://WebService/Database.Database.ssdl|res://WebService/Database.Database.msl; .../>
      </connectionStrings>

在 Database.Context.tt 中添加第二个构造函数(注意:这是自动生成的代码)

public <#=code.Escape(container)#>(string connectionString)
    : base(connectionString)
{
}

使用

using (EntityContainer context = new EntityContainer())
{
    //...
}

using (EntityContainer context = new EntityContainer("ArchiveEntityContainer"))
{
    //...
}

3
每当 EF 模板重新运行时,这个方法就会失效。如果想要更可靠的方法,请参考Olivier Hélin的这篇博客文章 - Aaroninus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接