在多个数据库上使用实体框架

29

我正在编写一款工资系统,它将与现有系统集成。原始系统有一个主数据库,处理用户管理和一些全局配置,下面有多个数据库,每个数据库的结构都相同,基本上每个数据库就是一个公司的工资数据库,所有这些都与主数据库关联,因为它属于一个母公司,该母公司拥有许多子公司,每个子公司都有自己的人力资源部门。

我想知道的是,是否有任何方法可以根据用户输入(使用cookie或其他存储方法)动态更改实体框架的目标数据库,并使用过滤器来实现?

这里有一个例子:

用户A登录网站,页面加载了用户有权限访问的可用公司,用户随后选择一个公司,在该公司中他们拥有管理员权限,添加员工之前,asp.net将切换到适当的数据库连接字符串,然后添加记录。


最多你会有2个上下文,或者有一些变通方法但很不实用,EF6有望支持多数据库。你可以检查beta版,在你的应用准备好的时候,EF6将发布。但是如果所有的数据库都是一个组织的一部分,那么将它们合并,并添加一个额外的外键CompanyID将会形成一个数据库,并使报告更容易。 - Akash Kava
1
啊,我明白了,问题在于第一个工资单系统的制作者非常坚持让我们保持数据库结构不变,他说这样公司就更愿意升级到新版本,因为他们不需要进行任何数据库迁移。 - clifford.duke
这是一个维护的噩梦,你将无法使用连接进行跨数据库查询。我不确定EF6,但你可以在codeplex上检查一下。 - Akash Kava
我不太担心跨数据库查询,因为子公司不应该访问彼此的数据库。谢谢提供信息,我会看一下EF6。 - clifford.duke
2个回答

27

这很简单。我有:

public WMSEntities() : base("name=WMSEntities") //WMSEntities is conection string name in     web.config also the name of Entitiframework
{
}

已经在edmx文件夹的自动生成的Model.Context.cs中了。

为了在运行时连接到多个数据库,我创建了另一个构造函数,该构造函数接受连接字符串作为参数,就像下面在同一文件Model.Context.cs中所示。

public WMSEntities(string connStringName)
    : base("name=" + connStringName)
{
}

现在我在Web.Config中添加了另一个连接字符串,例如

<add name="WMSEntities31" connectionString="data source=TESTDBSERVER_NAME;initial catalog=TESTDB;userid=TestUser;password=TestUserPW/>

<add name="WMSEntities" connectionString="data source=TESTDBSERVER_NAME12;initial catalog=TESTDB12;userid=TestUser12;password=TestUserPW12/>

接着,当连接到数据库时,我调用以下方法,并将连接字符串名称作为参数传递:

public static List<v_POVendor> GetPOVendorList(string connectionStringName)
{
    using (WMSEntities db = new WMSEntities(connectionStringName))
    {               
        vendorList = db.v_POVendor.ToList();                 
    }
}

2
嗨,这看起来很棒...我的问题是,如果有任何数据库模型更改,它会产生什么影响。这会成为维护的噩梦吗? - nikudale
如果我们重新生成model.cs文件,那么我们必须再次添加配置public WMSEntities(string connStringName) : base("name=" + connStringName) - Narendra Singh Rathore

7

EF6对于从同一上下文中访问多个数据库的支持更好。以下是来自EF5的代码片段。

在之前管理数据库初始化设置很重要。

您可能不想触发任何迁移。

即,在此之前使用以下代码:

Database.SetInitializer(new ContextInitializerNone<MyDbContext>());

但是,回答这个问题:是的,你可以。

var conn = GetSqlConn4DbName(dataSource,dbName );
var ctx = new MyDbContext(conn,true);



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;
    }


 public class ContextInitializerNone<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
{
    public void InitializeDatabase(TContext context) {  }
}

还可以查看使用迁移、示例代码和动态数据库连接的StackOverflow答案


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