📅  最后修改于: 2020-11-19 05:43:50             🧑  作者: Mango
在本章中,我们将介绍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-6cf049ee52be
Press 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方法是什么,因此您将获得RunTime异常。
异常表明无法识别的方法调用。在这里,我们正在做显而易见的事情,但不一定奏效。
让我们尝试其他方法,例如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。
如您所见,名字等于A%,但不等于。在SQL中,与like运算符一起使用A%。现在,我们需要在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-6cf049ee52be
Austyn 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-6cf049ee52be
Antonia 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将数据拉出数据库。