我对NHibernate相当新,我见过的大多数示例都在基类Criterion
或DetachedCriterion
类上添加了一些抽象层。在简单的情况下,它是某种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使用该对象来检索记录。
当然,这个例子是一个粗略的过度简化。在我的项目中,我已经开始创建一个包含Query<T>
和AND
条件的OR
类,并且界面定义了一种翻译我的自定义条件的方法(在有些情况比上面简单的QueryCondition
示例复杂得多)加入AbstractCriterion
以添加到服务中内置的DetachedCriterion
。我这样做的部分原因是我坚持查询关联,因此用户可以定义列表并保存它,但最大的原因是它似乎是我见过的n层NHibernate项目的主流方法。 p>
然而,我开始怀疑这种抽象的开销是否值得。它不会保存我对NHibernate的依赖。因为我使用期货来批量查询,所以我的项目都必须引用NHibernate至少访问IFutureValue
以获取记录计数。最重要的是,我的Query<T>
类与NHibernate密不可分,因为它构建了AbstractCriterion
(尽管我可以很容易地将它拉到一个单独的类中)。
无论如何,我看得越多,我就可以用Query<T>
替换我的DetachedCriteria
。两者都是可序列化的,所以我可以坚持它们,因为我不会建立与标准本身分开的标准条件,我认为我不太可能遇到复杂查询的别名问题。就抽象而言,这个抽象似乎并没有提供太多的复杂性。
任何人都可以告诉我为什么我应该抽象NHibernate标准而不是“你可能有一天会改变你的ORM”(我很乐意在项目的这个阶段说不可能) ?
答案 0 :(得分:0)
它在单元测试方面具有优势。 Criteria
API非常适合构建查询,但对于模拟来说真的很痛苦。如果您有这样的课程,您可以轻松验证条件:
query.Conditions.Contains(requiredCondition);
在Criteria中你需要一些模拟并验证应用程序的行为,而不是输出更难。
由于这个原因,我仍在我的应用中使用Repository
模式,而不是直接使用ISession