Fluent NHibernate 中的 DB 特定约定

Posted

技术标签:

【中文标题】Fluent NHibernate 中的 DB 特定约定【英文标题】:DB specific conventions in Fluent NHibernate 【发布时间】:2011-10-28 03:49:01 【问题描述】:

我有一套 Fluent NHibernate 约定,其中大部分是独立于数据库的。但是,对于字符串属性,有一些依赖于 DBMS:

Public Sub Apply(ByVal instance As IPropertyInstance) Implements IConvention(Of IPropertyInspector, IPropertyInstance).Apply
    instance.CustomSqlType("VARCHAR2(50 BYTE)")
End Sub

真的,我只是使用这样的约定来生成数据库(即对象首先开发)。这对 Oracle 来说效果很好,但我想使用内存中的 SQLite DB 进行单元测试,显然这种约定不起作用,因为 SQLite 没有 VARCHAR2 类型。

对于在这种情况下如何配置 Fluent NHibernate,是否有人有任何好的建议或参考。

目前,我正在考虑拥有一组独立于数据库的通用约定,然后将依赖的约定放在子目录/命名空间中。然后我会有某种配置,允许我指定一个自定义 ITypeSource 组件,该组件将获取所有通用约定以及与特定 DBMS 相关联的约定,例如SqlConventionTypeSource、OracleConventionTypeSource...

亲切的问候, 瑞恩。

【问题讨论】:

【参考方案1】:

您通常在可执行文件中设置您的约定(以及您流畅的配置的其余部分)。

这意味着您将在您的 GUI、您的单元测试以及其他任何碰巧使用您的基于 ISession/ISessionFactory 的服务中拥有不同的流畅配置。

在我看来,您已经对配置进行了硬编码,现在正试图弄清楚如何让“配置器”根据有关环境的某些信息采取不同的行动。

一种更简单的方法是在顶层创建配置并将其作为依赖项提供给任何需要它的对象。这样一来,您就不会被从不同环境中硬塞到相同的代码路径中。

无论是什么依赖于 NHibernate,将其设置为接受 ISessionISessionFactory 作为构造函数参数或属性设置器。那你就不会有这个问题了。您甚至可以为实际上不需要查询数据存储的测试模拟它。

当然,您仍然可以将创建 FNH 配置的任何类设置为自身可配置,并在配置行中使用条件语句。但通常 FNH 配置一开始就只有几行代码,这似乎不值得。只需为 SQL Server、Oracle、SQLite 等创建完全独立的配置。这样您就不必在每次进行细微更改时都对其进行持续维护。

【讨论】:

感谢 Aaronaught 的回复。 仅供参考;我使用 Castle.Facilities.NHibernateIntegration 库来配置 NHibernate 和 Windsor IoC。这样,我所有使用 NHibernate 的服务/演示者都可以使用 ISessionManager 作为必需/可选的类依赖项来创建。当我解析服务时,Windsor 将注入 ISessionManager 具体实现。基本上,我真的不需要太担心使用该工具的会话管理(例如,每个请求的打开会话),它使我能够通过模拟 ISessionManager 进行良好的单元测试。 我可以通过设施 IConfigurationBuilder 接口修改会话工厂的默认配置,在该接口中,我使用带有约定的自动映射流畅地配置 NHibernate 会话工厂。我需要告诉 FNH AutoPersistenceModel 在哪里可以找到约定,因为它们相当复杂、定义明确并且不太可能改变,所以它们是重用的良好候选者。这又回到了我原来的问题,我的一些约定是特定于数据库的(即那些用于生成模式的约定)。 @Ryan:如果您使用依赖注入,这似乎不是问题。您实际上是在使用 IoC 进行注入,还是在依赖某种单例/服务定位器模式?您应该能够专门为您的测试创建一个不同的 ISessionManager 实现,并将其传递给任何需要测试的地方。

以上是关于Fluent NHibernate 中的 DB 特定约定的主要内容,如果未能解决你的问题,请参考以下文章

Nhibernate Fluent 日期时间映射在 DB 中创建空列

通过(Fluent)NHibernate添加到SQLite DB时,DateTime不正确

Fluent NHibernate 忽略 ClassMap 中的属性,使用 FluentMappings

如何结合 NHibernate Fluent 和 WPF-NHibernate 工具包中的 VmWrapper-Classes?

如何在Fluent NHibernate中映射受保护的集合?

NHibernate 2 + Fluent Nhibernate 中等信任