开发手册 欢迎您!
软件开发者资料库

NHibernate - QueryOver查询

NHibernate QueryOver查询 - 从概述,架构,Orm,环境设置,入门,基本Orm,基本Crud操作,Profiler,添加Intelliesnse到映射文件,数据类型映射,配置,覆盖配置,批量大小,缓存,映射,学习NHibernate组件,关系,集合映射,级联,延迟加载,反向关系,加载/获取,Linq,Hibernate查询语言,条件查询,QueryOver查询,本机Sql,流利Hibernate。

在本章中,我们将介绍QueryOver查询.这是一种新的语法,它更像LINQ,使用方法链语法,如下面的查询所示.

var customers = session.QueryOver() .Where(x => x.FirstName == "Laverne");


  • 它仍然是标准,但现在我们的查询是强类型的.

  • 正如我们在条件查询中看到的那样,第一个名称只是一个不透明的字符串,现在我们实际上使用的是 x.FirstName ,所以第一个名称被重构并重命名,使用查询结果在链接样式条件查询中被更改.

  • 我们仍然可以做很多类似的事情,但是你不能将查询理解语法与查询结合使用,你必须使用方法链语法,你不能混合和匹配链接和标准.

  • 对于大量查询,通过API查询非常有用,并且比直接使用Criteria更容易理解对象语法.

让我们看一个简单的例子,我们将使用查询来检索名字为Laverne的客户.

using System; using System.Data; using System.Linq; using System.Reflection; using HibernatingRhinos.Profiler.Appender.NHibernate; using NHibernate.Cfg; using NHibernate.Criterion; using NHibernate.Dialect; using NHibernate.Driver; using NHibernate.Linq;namespace NHibernateDemo {    internal class Program {             private static void Main() {          var cfg = ConfigureNHibernate();          var sessionFactory = cfg.BuildSessionFactory();         using(var session = sessionFactory.OpenSession())                   using(var tx = session.BeginTransaction()) {             var customers = session.QueryOver()                .Where(x => x.FirstName == "Laverne");                         foreach (var customer in customers.List()) {                Console.WriteLine(customer);             }             tx.Commit();          }         Console.WriteLine("Press  to exit...");          Console.ReadLine();       }            private static Configuration ConfigureNHibernate() {          NHibernateProfiler.Initialize();         var cfg = new Configuration();                   cfg.DataBaseIntegration(x => {             x.ConnectionStringName = "default";             x.Driver();             x.Dialect();             x.IsolationLevel = IsolationLevel.RepeatableRead;             x.Timeout = 10;             x.BatchSize = 10;          });         cfg.SessionFactory().GenerateStatistics();         cfg.AddAssembly(Assembly.GetExecutingAssembly());          return cfg;       }    } }


正如您所看到的那样,它仍然是标准,但只是一个更好的语法.

编译并执行上述代码时,您将看到以下输出.

Laverne Hegmann (4e97c816-6bce-11e1-b095-6cf049ee52be)   Points: 74   HasGoldStatus: True   MemberSince: 4/4/2009 12:00:00 AM (Utc)   CreditRating: Neutral   AverageRating: 0   Orders:      Order Id: 4ea14d96-6bce-11e1-b095-6cf049ee52be      Order Id: 4ea14d96-6bce-11e1-b096-6cf049ee52be      Order Id: 4ea14d96-6bce-11e1-b097-6cf049ee52be      Order Id: 4ea14d96-6bce-11e1-b098-6cf049ee52bePress  to exit...


其中一个缺点是,假设我们要说 FirstName.StartsWith("A")如以下程序所示.

var customers = session.QueryOver() .Where(x => x.FirstName.StartsWith("A")); foreach (var customer in customers.List()) {    Console.WriteLine(customer); } tx.Commit();


现在让我们再次运行应用程序,您将看到这不是LINQ提供程序,因为它不知道这是什么 StartsWith 方法是,所以你会得到一个运行时异常.

运行时异常

异常表示无法识别的方法调用.在这里我们做了一件显而易见的事情,但它并不一定有用.

让我们尝试别的东西,比如FirstName等于"A%",如下面的代码所示.

var customers = session.QueryOver() .Where(x => x.FirstName == "A%"); foreach (var customer in customers.List()) {    Console.WriteLine(customer); }


让我们再次运行这个,你会看到我们不会得到任何结果,如下所示.

Press  to exit...


要理解为什么我们没有得到任何结果,让我们来看看NHibernate profiler.

结果NHibernate配置文件

您可以看到第一个名称等于A%,而不是.在SQL中使用%with with like运算符.现在我们需要在WHERE子句中创建一个限制,如下面的程序所示.

var customers = session.QueryOver()    .Where(Restrictions.On(c => c.FirstName).IsLike("A%")); foreach (var customer in customers.List()) {    Console.WriteLine(customer);}


让我们再次运行您的应用程序,您将看到以名字开头的所有客户都以A开头.

Alejandrin Will (4ea3aef6-6bce-11e1-b0b4-6cf049ee52be)   Points: 24   HasGoldStatus: False   MemberSince: 10/1/2011 12:00:00 AM (Utc)   CreditRating: VeryVeryGood   AverageRating: 0   Orders:      Order Id: 4ea3aef6-6bce-11e1-b0b5-6cf049ee52beAustyn Nolan (4ea871b6-6bce-11e1-b110-6cf049ee52be)   Points: 67   HasGoldStatus: True   MemberSince: 12/29/2007 12:00:00 AM (Utc)   CreditRating: Neutral   AverageRating: 0   Orders:      Order Id: 4ea871b6-6bce-11e1-b111-6cf049ee52beAntonia Murphy (4ea871b6-6bce-11e1-b121-6cf049ee52be)   Points: 72   HasGoldStatus: True   MemberSince: 6/15/2009 12:00:00 AM (Utc)   CreditRating: Terrible   AverageRating: 0   Orders:      Order Id: 4ea871b6-6bce-11e1-b122-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b123-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b124-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b125-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b126-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b127-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b128-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b129-6cf049ee52be      Order Id: 4ea871b6-6bce-11e1-b12a-6cf049ee52be


除了使用这个新的 QueryOver 语法之外,它的工作方式与之前相同.许多开发人员发现LINQ语法更容易接近并且经常做正确的事情.

如果LINQ无法处理它,那么你将开始查看HQL或Criteria以查看是否会更合适.

它只是为您提供了不同的语法,因此Criteria,创建条件和QueryOver为您提供了另一种查询机制,允许您从数据库中提取数据使用NHibernate.