将entity framework与多个MS SQLSERVER数据库一起使用
我来回搜索,但似乎无法掌握我需要的东西。 如果最近得到回答,我很抱歉。 重新定向讨论对我有好处。
这就是场景。 我被指示从我的老板转移到Microsoft Visual Foxpro(MS正在撤回2015年的支持)到.Net C#。 为了良好的基础和最佳实践的采用,我决定先学习,将相关信息拼凑起来,然后开始编码。 这是第二年。
我们是一家上市公司,为50多个客户提供工资处理外包服务。 每个客户端目前都有自己的数据库。 数据库具有完全相同结构的表。
我是新手。 完全是.net世界的新东西。
我从使用数据表,数据加载器的原始SQL开始,但在我的研究中,我得到了一些讨论令人沮丧。 许多人认为entity framework应该达到目的。 但是,允许混合方法,特别是涉及复杂查询时。
有人能指出我的一些“好读”,我可以用50多个缩进数据库实现Entity Framework。 每个数据库都是完全独立的,没有任何其他数据库。 当用户登录时,他们选择处理工资单所需的客户端,然后EF指向该数据库。
EF需要2条不同的信息来处理数据库中的数据:
1)数据库模式:它作为编译代码包含在应用程序中,通常不能在运行时更改。
2)连接字符串:这是在运行时提供的,通常来自配置文件。
在您的情况下,所有数据库都具有相同的模式,因此您可以只模拟一个数据库,它将适用于所有其他数据库。
您要更改的部分是连接字符串。 这告诉EF如何查找数据库,并且可以在运行时提供。
DbContext
构造函数有一个重载, 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") { }
已经在自动生成的edmx文件夹的Model.Context.cs中
为了在运行时连接到多个数据库,我创建了另一个构造函数,它在同一个文件Model.Context.cs中将连接字符串作为参数如下所示
public WMSEntities(string connStringName) : base("name=" + connStringName) { }
现在,我在Web.Config中添加了其他连接字符串
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是现有数据库支持的现场野兽,但它有点像配置工作,看似政治内斗导致文档对于不同版本和分叉的冲突。
更简单的是许多“ 微型ORM ” – 这个链接是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是Project中扩展DbContext(任何EF项目的标准部分)的主要EF类。
一次只谈一个
如果你只使用每个应用程序一个,那么任何EF教程都可以 。
唯一的主要技巧是在发生架构更改时迁移这些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实例上。 一个很好的例子就是你可以从你的迁移中获得明确的错误,以及完全的回滚function,而不需要任何实际工作 – 所有你正在利用的回滚支持只是EF的一部分。 一个开发人员可以做到这一点,没有一堆其他瓶颈。 但它有很多机会降低风险并提高自动化程度。