8

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

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

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

我是新手。对.net 世界来说是全新的。

我开始使用数据表、数据读取器使用原始 SQL,但在我的研究中,我得到了一些令人沮丧的讨论。许多人认为实体框架应该服务于目的。但是允许混合使用方法,尤其是在涉及复杂查询时。

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

4

3 回答 3

4

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

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

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

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

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

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

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

MSDN: EntityConnectionStringBuilder Class

MSDN: Connection String Builders

于 2013-04-02T09:01:54.673 回答
3

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

你应该使用 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是现有数据库支持的现场野兽,但它有点像配置工作,而且似乎是政治内讧导致文档在不同版本和分支之间发生冲突。

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

回答您的具体问题

一次与所有客户端数据库对话

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

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 类。

一次只与一个人交谈

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

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

显而易见的 - SQL 脚本

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

我对少量数据库的疯狂方式

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

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

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

于 2013-04-02T09:02:25.657 回答
3

这很简单

我有,

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

已经在 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/>

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

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

      }
  }
于 2014-01-03T01:47:51.763 回答