【问题标题】:Is there value in abstracting NHibernate criterion?抽象 NHibernate 标准是否有价值?
【发布时间】:2012-01-11 00:10:53
【问题描述】:

我对 NHibernate 还很陌生,我见过的大多数示例都在基本的 CriterionDetachedCriterion 类之上添加了一些抽象层。在简单的情况下,它是某种 Query 类,可能看起来像这样:

public class Query<T>
{
    public List<QueryCondition> Conditions { get; set;}
}

public class QueryCondition
{
    public string Property { get; set; }
    public ComparisonEnum Comparison { get; set; }
    public object Value { get; set; }
}

在服务或存储库层的某个地方,查询抽象被转换为适当的Criterion 对象,然后 NHibernate 使用该对象来检索记录。

当然,这个例子过于简单化了。在我的项目中,我创建了一个包含ANDOR 条件的Query&lt;T&gt; 类,并且接口定义了一种方法来翻译我的自定义条件(在某些情况下比上面简单的QueryCondition 示例)到AbstractCriterion 添加到服务中内置的DetachedCriterion。我这样做的部分原因是我保持关联的查询,以便用户可以定义一个列表并保存它,但最大的原因是它似乎是我见过的 n 层 NHibernate 项目的流行方法。

但是,我开始怀疑这种抽象的开销是否值得。它不会拯救我对 NHibernate 的依赖。因为我使用期货来批量查询,所以我的项目都必须引用 NHibernate 才能至少访问 IFutureValue 以获取记录计数。最重要的是,我的 Query&lt;T&gt; 类与 NHibernate 有着千丝万缕的联系,因为它构建了 AbstractCriterion(尽管我可以轻松地将其拉出到单独的类中)。

不管怎样,我看的越多,我就可以简单地将我的Query&lt;T&gt; 替换为DetachedCriteria。两者都是可序列化的,因此我可以将它们持久化,并且由于我不会将标准条件与标准本身分开,我认为我不太可能遇到复杂查询的别名问题。就抽象而言,这个似乎并没有提供太多的复杂性。

谁能给我为什么我应该抽象 NHibernate 标准的原因除了“你可能有一天会改变你的 ORM”(我很高兴地说在项目的这个阶段是不可能的) ?

【问题讨论】:

    标签: nhibernate


    【解决方案1】:

    它在单元测试方面具有优势。 Criteria API 在构建查询方面非常出色,但对于模拟来说真的很痛苦。如果您有这样的课程,您可以轻松验证条件:

     query.Conditions.Contains(requiredCondition);
    

    在 Criteria 中,您需要一些模拟和验证应用程序的行为,而不是更难的输出。

    仅仅因为这个原因,我仍然在我的应用程序中使用Repository 模式,而不是直接使用ISession

    【讨论】:

    • 我还没有进行单元测试(我现在可以听到来自 SO 社区的喘息声),但你的观点是有道理的。它还突出了一个问题——我的服务层,主要是一个根据用户的安全权限过滤数据的安全服务,它将Query&lt;T&gt; 转换为Criterion。这意味着对这些服务方法(主要是并行存储库方法)进行单元测试也很困难。
    • 而不是query.Conditions.Contains(requiredCondition); 为什么不用每个边缘情况的数据填充内存数据库并运行查询。不需要额外的翻译层,并且它具有实际测试真实查询而不是您认为会导致正确结果的条件的额外好处。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 1970-01-01
    • 2014-05-05
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多