在具有相同架构的多个数据库中使用 EF(或另一个 .NET ORM)
Posted
技术标签:
【中文标题】在具有相同架构的多个数据库中使用 EF(或另一个 .NET ORM)【英文标题】:Using EF (or another .NET ORM) across multiple databases w/ identical schemas 【发布时间】:2013-12-06 15:01:49 【问题描述】:请原谅我对 EF 和/或 ORM 术语的无知。我熟悉 ORM 及其用途,但找不到支持我的用例的 ORM。
我有用于不同客户端的独特数据库,分布在 3 个数据库服务器上。但是,这些不同数据库的模式是准确的。我的问题是,我怎样才能让 EF(或另一个 .NET orm [NHibernate?])支持这种类型的架构?当我从数据库生成模型时,它似乎为该单个数据库创建了一个连接字符串。我需要它来确定要在运行时使用的正确连接字符串。
那么,为每个唯一的客户端数据库(不会扩展)保存生成模型,我该怎么办?
感谢任何帮助或指导。
【问题讨论】:
【参考方案1】:不可能写出通用的答案,因为每个 ORM 都有自己的规则(我把它做成了一个社区 wiki 来合并其他答案)。
实体框架
使用连接字符串(通常在app.config
文件中)声明它将使用哪个数据库。当您创建上下文时,它将读取默认值,但有一个构造函数接受它作为参数:
string connectionString = "...";
using (var repository= new MyRepository(connectionString))
通常 EF 连接字符串(在其自己的模型数据之后)为提供者定义一个 标准 连接字符串:
provider=System.Data.SqlClient;provider connection string= "data source=tcp:serverName;initial catalog=databaseName;user id=username;
不要忘记从代码中转义"
。您可以从app.config
文件中读取完整的连接字符串(以使用它,例如作为搜索和替换的模板)。在这种情况下,您说:“让我们使用与 Microsoft SQL Server 的连接,这是它的连接字符串”。只需将initial catalog
更改为您要连接的数据库即可。
开发快递
string connectionString = "...";
XpoDefault.DataLayer = XpoDefault.GetDataLayer(
connectionString,
AutoCreateOption.DatabaseAndSchema);
光速
从ConnectionStrategy
继承并覆盖Connection
属性。要使用它,您可以设置 ModelUnitOfWork
对象的 ConnectionStrategy
属性。
NHibernate
从NHibernate.Connection.DriverConnectionProvider
类继承并覆盖GetConnection()
方法。详情请见this example。
【讨论】:
感谢您的提醒。任何想法为什么会犹豫使用“数据源”作为关键字?我得到一个Keyword not supported: 'data source'。 @William 您应该为您的连接字符串发布代码。如果我不得不猜测,我会说这是因为它没有正确转义。 你是对的。我错误地转义了“!非常感谢。 @AdrianoRepetti 感谢您的回答 - 我对这个问题有一个推论。如果我有相同的模式,但需要在不同的数据库中表示相同的对象(可以访问子客户端信息的主客户端),是否有适当的方法来建立这种关系,或者使用无状态会话或.AsNoQuery() 用于实体框架并作为应用程序的一部分管理连接。【参考方案2】:举几个例子:
使用 DevEpxress XPO ORM 时,您可以执行以下操作:
XpoDefault.DataLayer = XpoDefault.GetDataLayer("TheConnectionString, AutoCreateOption.DatabaseAndSchema);
当首先使用 EF 代码时
public class SiteContext : DbContext
public SiteContext(): base("TheConnectionString")
使用 LightSpeed ORM 时:
查看链接:http://www.mindscapehq.com/documentation/lightspeed/Building-Applications-with-LightSpeed/Customising-How-LightSpeed-Connects-to-the-Database
在我看来很难选择哪个 ORM,而我现在要输入的内容相当有偏见:
DevExpress ORM XPO。出色的 ORM 映射器,尤其是与 XAF 等产品线结合使用时。他们的支持非常好。
EF 代码首先使用起来非常简单。有传言说它与其他 ORM 映射器相比相当慢。
Mindscape Lightspeed 专注于速度和设计时间功能。很好的支持。
我参与了使用 NHibernate 作为 ORM 映射器的项目。一般认为它是高度可定制的。我曾在 EF 未能映射 NHibernate 没有的 Oracle 现有数据库的项目中工作过。 NHibernate 适合不太容易学习的新手。
对于您的情况,首先必须检查 ORM 映射器对您的数据库模型的处理能力,这一点很重要。
【讨论】:
【参考方案3】:我刚刚扩展了我们的系统以支持多租户,其中每个租户都由一个单独的数据库支持。我们的系统使用 NHibernate。
我的解决方案很简单:只需继承NHibernate.Connection.DriverConnectionProvider
类,重写GetConnection()
方法即可返回正确的连接。有了这个,您可以使用一个 SessionFactory 对象来管理具有相同架构的多个数据库。
当然,实现要复杂得多,但它涉及将整个系统从单租户调整为多租户。
【讨论】:
以上是关于在具有相同架构的多个数据库中使用 EF(或另一个 .NET ORM)的主要内容,如果未能解决你的问题,请参考以下文章
ObjectStateManager 中已存在具有同一键的对象。ObjectStateManager 无法跟踪具有相同键的多个对象