将实体框架与多个MS SQLSERVER数据库一起使用

时间:2013-04-02 08:41:49

标签: c# sql-server

我来回搜索,但似乎无法掌握我需要的东西。如果最近得到回答,我很抱歉。重新定向讨论对我有好处。

这就是场景。我被指示从我的老板那里转移到Microsoft Visual Foxpro(MS正在撤回2015年的支持)到.Net C#。为了良好的基础和最佳实践的采用,我决定先学习,将相关信息拼凑起来,然后开始编码。这是第二年。

我们是一家上市公司,为50多个客户提供工资单处理外包服务。每个客户端目前都有自己的数据库。数据库具有完全相同结构的表。

我是新手。完全是.net世界的新东西。

我从使用数据表,数据加载器的原始SQL开始,但在我的研究中,我得到了一些讨论令人沮丧。许多人认为实体框架应该达到目的。但是,允许混合方法,特别是涉及复杂查询时。

有人可以指点一些“好读”,我可以用50多个缩进数据库实现Entity Framework。每个数据库都是完全独立的,没有任何其他数据库。当用户登录时,他们选择处理工资单所需的客户端,然后EF指向该数据库。

3 个答案:

答案 0 :(得分:4)

EF需要2条不同的信息来处理数据库中的数据:

1)数据库模式:它作为编译代码包含在应用程序中,通常不能在运行时更改。

2)连接字符串:这是在运行时提供的,通常来自配置文件。

在您的情况下,所有数据库都具有相同的模式,因此您只需建模一个数据库,它将适用于所有其他数据库。

您要更改的部分是连接字符串。这告诉EF如何查找数据库,并且可以在运行时提供。

DbContext构造函数有一个重载,它将连接字符串作为参数:MSDN: DbContext Constructor (String)

框架中甚至有一些类可以帮助您创建连接字符串:

MSDN: EntityConnectionStringBuilder Class

MSDN: Connection String Builders

答案 1 :(得分:3)

Hrmmm我碰巧真的喜欢EF Code First,但我不确定它是否适合你正在做的事情。您的架构多久更改一次?

您应该使用EF吗?

EF

的优点

如果架构有所变化,EF Code First的迁移部分可能会节省大量的时间和精力,因为您经常可以使用SQL脚本进行架构升级 - 架构更改最终会在源存储库中与其他库存更新你的代码。你从这里开始:

https://stackoverflow.com/a/8909092/176877

我也很喜欢EF设置的简单程度,以及编写LINQ查询并简单地返回我从数据库构建的POCO是多么容易。

但EF可能不是最合适的。

要考虑的其他ORM

许多其他ORM支持LINQ和POCO,对现有数据库有更好的支持(在EF Code First中可能很难映射),以及现有的异步操作支持(EF现在5.0; 6.0有异步) - (更新:EF6是最新的,它的异步支持很棒。虽然它的批量删除很糟糕,应该像瘟疫一样避免,为此删掉普通的SQL。)

特别是NHibernate是现有数据库支持的现场野兽,但它有点像配置工作,看似政治内斗导致文档因不同版本和分叉而发生冲突

更简单的是许多“Micro ORMs” - 这个链接是2011年的一个简短列表,但如果你四处寻找,你会在.Net中找到30个左右。有些会生成更好或更不理想的查询,有些根本没有,有些会让你编写SQL(不要使用那些) - 你必须四处寻找决定哪个适合你。这可能是一项更大的研究任务,但我怀疑其中一种最容易配置和小学习曲线适合您正在尝试做的事情。

回答您的具体问题

立即与所有客户Dbs交谈

如果您同时从一个应用程序连接到所有50个数据库,则需要实例化50个DbContexts,如:

var dbClient1 = new DbClient1();
var dbClient2 = new DbClient2();

假设你去做了一些小包装类,比如:

public class DbClient1 : CoreDbContext
{
    public DbClient1()
        : base("DbClient1") // Means use the connection string named "DbClient1" in Web.Config

其中CoreDbContext是项目中扩展DbContext(任何EF项目的标准部分)的主要EF类。

一次只与一个人交谈

如果您每个应用只使用一个,那么any EF tutorial will do

唯一的主要技巧是在发生架构更改时迁移这些Dbs。有两种基本方法。无论哪种方式,您都可以获取备份并在本地恢复它们的副本,以便您可以针对它们测试迁移(update-database -f -verbose)。如果你不这样做,你冒着数据错误的风险,例如将列更改为NOT NULL,并且发现本地测试实例没有空值,一个客户端做了,kaboom。一旦你让它们工作,你就决定如何更新生产。您可以通过多种方式执行此操作,包括编写自定义前滚/后退工具(或查找一个),将SQL脚本检入git,雇用DBA或更简单:

明显 - SQL脚本

将迁移转储到SQL(update-database -script)并针对实际的生产数据库运行。

我少数Dbs的疯狂方式

将每个数据库的条目添加到Web.Config,并为每个数据库创建一个项目配置,如“DbDeployClient1”,“DbDeployClient2”等。在每个数据库中创建一个类似于DbDeployClient1的构建定义,然后将其添加到您的DbContext类:

public CoreDbContext()
#if DbDeployClient1
    : base("DbDeployClient1")
#elseif DbDeployClient2
    : base("DbDeployClient2")
    // etc
#endif
{

这使您可以快速切换到DbDeploy配置,并直接从Visual Studio对目标数据库运行迁移。显然,如果你这样做,你需要临时打开一个端口,最好只允许你的IP,在你正在迁移的实际SQL Server实例上。一个很好的例子就是你可以从你的迁移中获得明确的错误,并且完全回滚功能,没有任何实际工作 - 所有你正在利用的回滚支持只是EF的一部分。一个开发人员可以做到这一点,没有一堆其他瓶颈。但它有很多降低风险和提高自动化的机会。

答案 2 :(得分:3)

非常简单

我有,

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

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

为了在运行时连接到多个数据库,我创建了另一个构造函数,它在同一个文件中将连接字符串作为参数如下所示。模型.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/>

然后,当连接到数据库时,我调用下面的方法传递connetionString名称作为参数

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

      }
  }
相关问题