关于orm:使用NHibernate进行查询的最佳实践

关于orm:使用NHibernate进行查询的最佳实践

Best practices for querying with NHibernate

在使用其他技术(CSLA和Subsonic)几年之后,我又回到了NHibernate的使用,我发现查询有点令人沮丧,尤其是与Subsonic相比。 我想知道人们正在使用其他什么方法?

Hibernate Query Language不适用于我,似乎太像编写SQL,在我看来,这是使用ORM工具的原因之一,因此我不必再使用XML,这意味着 可重构性差,并且错误只会在运行时发现?

条件查询,似乎不够流畅。

我读过Ayende的NHibernate查询生成器,它是一个有用的工具,这是人们在使用的东西吗? 还有什么呢?

编辑:值得一读
http://www.ayende.com/Blog/archive/2007/03/17/Implementing-Linq-for-NHibernate-A-How-To-Guide--Part.aspx


LINQ for NHibernate仍在测试阶段。我期待NHibernate 2.1,他们说它最终会成功。

大约一个月前,我在NHQ的LINQ上进行了演示,您可能会发现它很有用。我在这里写了关于它的博客,包括幻灯片和代码:

LINQ for NHibernate:Visual Studio 2008幻灯片和代码中的O / R映射


要摆脱XML,请尝试Fluent NHibernate

Linq2NH尚未完全烘焙。核心团队正在与NH Contrib进行不同的实施。不过,它适用于简单查询。尽量不要使用,以取得最佳效果。

至于如何查询(hql相对于Criteria相对于Linq2NH),请在存储库接口上公开意图揭示方法(GetProductsForOrder(Order order)GetCustomersThatPurchasedProduct(Product product)等),并以最佳方式实现它们。使用hql进行简单查询可能会更容易,而使用规范模式时,您可能会发现Criteria API更合适。这些东西只是封装在您的存储库中,并且如果您的测试通过,则实现的方式无关紧要。

我发现Criteria API繁琐,有限但灵活。 HQL更像是我的风格(它比SQL更好-它是基于对象的,而不是基于模式的),并且对于简单的GetX方法来说似乎更适合我。


LINQ-to-NHibernate和Ayende的NHQG的替代方法是从C#3表达式生成NHibernate表达式/限制。这样,您可以获得类型更严格的Criteria API。

看到:

  • http://bugsquash.blogspot.com/2008/03/strongly-typed-nhibernate-criteria-with.html
  • http://www.kowitz.net/archive/2008/08/17/what-would-nhibernate-icriteria-look-like-in-.net-3.5.aspx
  • http://nhibernate.info/blog/2009/01/07/typesafe-icriteria-using-lambda-expressions.html

我默认将Linq用于NHibernate。当我遇到错误或限制时,我会切换到HQL。

如果将所有查询放在一个数据访问类(例如存储库)中,那么这是一种干净的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class CustomerRepostitory()
{
  //LINQ for NHibernate    
  public Customer[] FindCustomerByEmail(string email)
  {
     return (from c in _session.Linq<Customer>() where c.Email == email).FirstOrDefault();
  }

  //HQL
  public Customer[] FindBestBuyers()
  {
    var q = _session.CreateQuery("...insert complex HQL here...");
    return q.List<Customer>();
  }
}

您询问有关重构的问题。显然,IDE可以处理LINQ,因此,对于所有剩余的HQL,扫描这些存储库类并手动更改HQL相当容易。

将HQL放在XML文件中是一个好习惯,也许看看ReSharper NHIbernate插件现在是否可以处理查询重构?

编写或重构查询(HQL或LINQ)时的一个重大改进是将查找器方法置于单元测试之下。这样,您可以快速调整HQL / LINQ,直到出现绿色条。编译/测试/反馈循环非常快,尤其是当您使用内存数据库进行测试时。

另外,如果您在重构后忘记编辑HQL,则单元测试应使您很快了解损坏的HQL。


如果可以的话,请废弃nHibernate并返回Subsonic。在我看来,Subsonic是一种更加流畅和可测试的ORM / DAL。我绝对讨厌HQL在ORM中进行弱类型查询的目的是什么?当我只能使用Linq进行SQL并切出一层时,为什么还要使用Linq / nH / SQL?

当Subsonic不在时,nHibernate是一个很好的ORM,但是现在,与之相比,它简直太糟糕了。与nHibernate和Subsonic相比,我花了2倍的时间轻松完成工作。由于nHibernate是运行时,因此进行测试很麻烦,因此现在我需要聘请一些QA工程师来"单击"该站点,而不会出现编译时错误。


推荐阅读