.net - NHibernate 和多个数据库后端 - 架构

标签 .net asp.net nhibernate

我有一个项目应该在不同的(至少 2 个)数据库后端上运行,因此用户可以选择(目前在 MSSQL 和 SQLite 之间)。我刚刚开始学习 NHibernate,遵循 tutorial on nhibernate.info .

现在,我当前的架构如下所示:

我的项目.DAL

包含 新闻项目 INewsItemRepository . NewsItem 是一个 POCO,本质上只是一个 int Id 和字符串 Title。

INewsItemRepository 是包含 CRUD 功能的接口(interface)。

MyProject.Plugins.DAL.MSSQL

此类实现后端。它包括 hibernate.cfg.xml , NewsItem.hbm.xml NewsItemRepository .

cfg 保存 Driver 和 ConnectionString,hbm 是 SQL-Server 特定的 Mapping,NewsItemRepository 实现 INewsItemRepository。

如果我想添加 MyProject.Plugins.DAL.SQLite,我将不得不复制所有这些,这是合乎逻辑的。但是,我想知道这是否是正确的方法?我觉得我在不必要地重复一些东西。我的意思是:我需要确保映射是特定于数据库的,并且如果数据库发生更改,我会更新我的所有插件。但这种架构似乎仍然以某种方式......臃肿。

我在这里做正确的事吗?或者对于一般业务组合中的内容以及每个数据库需要单独保存的内容是否有共同的模式?

编辑:这里的挑战之一是处理 sql 类型。例如,字符串默认映射为 nvarchar(255),如果我在 MSSQL 中需要 ntext,我将不得不使用 标签的 .hbm.xml,然后在每个包含列的后端程序集中有一个 .hbm?

最佳答案

好吧,我还没有看到您的项目或数据模型,因此您必须将其解释为最适合您的情况。但是,是的,我的 react 是,这比必要的代码更多。

使用像 NHibernate 这样的 ORM 的主要好处之一是它们将您的代码与您的持久性架构分开。在我看来,多次映射 NewsItem(例如)是不必要的,例如。无论后端如何,数据模型是否都可能相同?也许你可以举一个他们可能不同的例子。

其次,我可能不会重新实现 NewsItemRepository。无论数据库后端如何,存储库都使用 NHibernate,其主要目的是抽象数据库。存储库处理的所有 CRUD 功能在 MSSQL 上与 SQLite 相同(除非数据模型实际上存在差异)。

如果你的数据库模型在两个后端都是一样的,理论上你应该只需要改变连接字符串来改变正在使用的数据库。我之前实现 DAL 的方式是像您一样提供接口(interface),然后为实现提供一个子命名空间,一个(嗯,目前唯一的一个;)是 NHibernate。存储库等。是通过依赖注入(inject)获得的。 DI 内核也处理 session 工厂,因此很容易为不同的代码部分定位不同的数据库。

当然,所有这些都假设您的数据模型在两个数据库引擎上都是相同的。如果不是,我的回答可能不是很有帮助。如果是这样的话,知道有什么不同可能会让我或其他人得到更好的答案。

编辑:

我明白你对 sql 类型的意思。但是,如果您是从 NHibernate 为您的数据库生成模式,那么这只是一个问题。映射属性时,不需要使用<column>以及您在 <property> 上指定的类型是 NHibernate 类型。 StringClob 类型将正确处理 NTEXT 字段。

如果您从 NHibernate 映射生成架构并且 NHibernate 不够聪明,无法为 SQLite 去除 sql-type="NTEXT"(我希望是这样,但我从未使用过架构生成工具),我想我会添加一个构建步骤来清理 SQLite 模式。当然,现在您正在增加流程的复杂性,所以这取决于您。但是,我宁愿让我的代码和映射尽可能简单和干净,只在需要的地方保持复杂性(数据库引擎的挑剔细节)。在我看来,保留两个单独的映射文件是缺少属性映射的秘诀,用户对为什么在使用 SQLite 时不能放入 DOB 感到摸不着头脑;)

EDIT2(关于 DI 与 NH 一起使用):

这有点主观,因为我确信有很多方法可以将 DI 与 NHibernate 一起使用。我在使用 DI 和 Fluent NHibernate 方面取得了巨大成功和 Ninject ,一个也使用“流利”DSL的DI框架。 Fluent NHibernate (FNH) 提供接口(interface)IPersistenceConfigurer用于创建数据库连接字符串(它还提供了许多方言可供选择)。因此,很容易绑定(bind) IPersistenceConfigurer通过 DI 框架向提供者提供服务。您可以对 ISessionFactory 执行相同的操作拥有一个完全注入(inject) D 的工厂。由于 Ninject 使用属性,我的存储库构造函数可能如下所示:

[Inject, CRM]
public MyRepository(ISessionFactory sessionFactory)

这将为 CRM 数据库注入(inject)一个工厂。我喜欢。 :)

关于.net - NHibernate 和多个数据库后端 - 架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/800249/

相关文章:

c# - 从描述属性中获取枚举

asp.net - 正确创建跨域表单例份验证 cookie

asp.net - 如何在 LINQ 中使用 IN 运算符

nhibernate - 在NHibernate(Fluent)中,如何将引用对象的属性映射到父对象?

.net - NHibernate 二级缓存与 AppFabric

.net - 是否可以在 linq to sql 的实体类中创建自定义方法

c# - 对普通类进行单元测试覆盖是好习惯吗

.net - 如何更改表达式中参数的类型?

.net - ANTS Memory Profiler - 我应该查看哪个内存?

NHibernate,如何将属性映射到子选择