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

本文关键字:MS SQLSERVER 数据库 实体 框架 | 更新日期: 2023-09-27 18:07:05

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

这是一个场景。我的老板指示我从Microsoft Visual Foxpro (MS将在2015年退出支持)转向。net c#。为了良好的基础和采用最佳实践,我决定先学习,将相关信息拼凑在一起,然后开始编码。这是第二年了。

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

我是一个新手。全新的。net世界

我开始使用原始SQL使用数据表,数据阅读器,但在我的研究中,我得到了一些不鼓励这样做的讨论。许多人认为实体框架应该达到目的。但是可以混合使用各种方法,特别是在涉及复杂查询时。

有人能给我指出一些"好的阅读",我可以实现实体框架与50多个相同的数据库。每个数据库都是完全独立的,与其他数据库无关。当用户登录时,他们选择需要为哪个客户处理工资单,然后EF指向该数据库。

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

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

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

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

在你的例子中,所有的数据库都有相同的模式,所以你可以只建模一个数据库,它将适用于所有其他的。

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

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

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

MSDN: EntityConnectionStringBuilder Class

MSDN: Connection String Builders

很简单

,

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

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

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

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

现在,我在Web中添加了其他连接字符串。配置例如

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

我碰巧真的很喜欢EF Code First,但我不确定它适合你正在做的事情。你的模式多久改变一次?

你应该使用EF吗?

EF的优点

如果模式有规律地更改,EF Code First的迁移部分可能会为您节省大量的时间和精力,因为您经常可以不使用SQL脚本进行模式升级——模式更改最终会与其他代码一起出现在源存储库中。从这里开始:

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

我也碰巧真的很喜欢EF的设置是多么容易,以及编写LINQ查询对它是多么容易,并返回我从DB构建的poco。

但是EF可能不是最合适的。

其他要考虑的orm

许多其他orm支持LINQ和POCOs,并更好地支持现有数据库(在EF Code First中有一些东西很难映射),以及现有的异步操作支持(EF现在是5.0;6.0有async)——(更新:EF6是最新的,它的异步支持很棒。它的批量删除是可怕的,应该避免像瘟疫一样,放弃普通的SQL)。

特别是NHibernate是现有数据库支持的野兽,但它的配置有点繁琐,而且似乎是政治上的内讧导致了不同版本和分支的文档冲突。

更简单的是许多&;Micro orms &;-这个链接是2011年的一个简短列表,但如果你四处看看,你会发现。net中有30个左右。有些会生成更好或更差的查询,有些根本没有,有些会让您编写SQL(不要使用这些)-您必须四处寻找以决定哪种适合您。这可能是一个更大的研究任务,但我认为其中一个简单的配置和小的学习曲线最适合你想做的。

回答你的具体问题

一次与所有客户端db对话

如果你同时从一个应用程序连接到所有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是项目中的主要EF类,它扩展了DbContext(任何EF项目的标准部分)。

一次只和一个人说话

如果你只使用一个应用程序,那么任何EF教程都可以。

唯一的主要技巧是在模式发生更改时迁移那些db。有两种基本方法。无论哪种方式,您都可以获取备份并在本地恢复它们的副本,以便您可以根据它们测试迁移(update-database -f -verbose)。如果不这样做,就会冒着数据错误的风险,比如将列更改为NOT NULL,并发现本地测试实例没有空值,一个客户端的测试实例没有空值,就会崩溃。一旦你让它们正常工作,你就开始决定你想要如何更新生产。有很多方法可以做到这一点,包括使用签入git的SQL脚本编写自定义前滚/回滚工具(或找到一个),雇佣DBA,或者更简单:

The Obvious - SQL Script

转储迁移到SQL (update-database -script),并在实际的生产数据库上运行它。

我的疯狂方式为少量的Dbs

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

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

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