博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NHibernate.3.0.Cookbook第四章第2节的翻译
阅读量:4678 次
发布时间:2019-06-09

本文共 5910 字,大约阅读时间需要 19 分钟。

Using Criteria Queries

使用条件查询

  在上一章中,通过实体的ID来获取这些实体.本节介绍几个基础的条件查询:通过实体的属性来获取实体.

步骤

1.   完成本章简介中的通用步骤.

2.   在Queries类中,添加下面的方法:

View Code
public IEnumerable
GetMoviesDirectedBy(string directorName){ return _session.CreateCriteria
() .Add(Restrictions.Eq("Director", directorName)) .List
();}

3.   在Queries类中,添加下面的方法,该方法通过actor name来查询movies:

View Code
public IEnumerable
GetMoviesWith(string actorName){ return _session.CreateCriteria
() .CreateCriteria("Actors", JoinType.InnerJoin) .Add(Restrictions.Eq("Actor", actorName)) .List
();}

4.   在Queries类中,添加下面的方法,该方法通过ISBN来查询book:

View Code
public Book GetBookByISBN(string isbn){  return _session.CreateCriteria
() .Add(Restrictions.Eq("ISBN", isbn)) .UniqueResult
();}

5.   添加下面的方法,该方法查找一定价格范围内的所有产品:

View Code
public IEnumerable
GetProductByPrice( decimal minPrice, decimal maxPrice){ return _session.CreateCriteria
() .Add(Restrictions.And( Restrictions.Ge("UnitPrice", minPrice), Restrictions.Le("UnitPrice", maxPrice) )) .AddOrder(Order.Asc("UnitPrice")) .List
();}

6.   在Program.cs中, 为RunQueries方法添加下述代码:

View Code
static void RunQueries(ISession session){  var queries = new Queries(session);  Show("Movies directed by Spielberg:",    queries.GetMoviesDirectedBy(    "Steven Spielberg"));  Show("Movies with Morgan Freeman:",    queries.GetMoviesWith(    "Morgan Freeman"));  Show("This book:",    queries.GetBookByISBN(    "978-1-849513-04-3"));  Show("Cheap products:",    queries.GetProductByPrice(0M, 15M));}

7.   编译运行,结果如下图所示:

原理

  让我们来逐一地来查看这四个查询:

  • GetMoviesDirectedBy 查询
View Code
_session.CreateCriteria
() .Add(Restrictions.Eq("Director", directorName)) .List
();

  上面的代码中,使用session.CreateCriteria获得了一个ICriteria对象.泛型参数Movie告诉NHibernate即将在movies上进行查询.代码第二行,movies约束条件为:由Steven Spielberg执导.最后,调用List方法,该方法执行查询并返回由Steven Spielberg执导的movies.由于泛型参数Movie,NHibernate返回了一个强类型IList<Movie>,而不是IList.

  在Microsoft SQL Server中, 生成的SQL语句如下:

View Code
SELECT   this_.Id          as Id1_0_,         this_.Name        as Name1_0_,         this_.Description as Descript4_1_0_,         this_.UnitPrice   as UnitPrice1_0_,         this_.Director    as Director1_0_FROM     Product this_WHERE    this_.ProductType = 'Eg.Core.Movie'         AND this_.Director = 'Steven Spielberg' /* @p0 */
  • GetMoviesWith 查询
View Code
_session.CreateCriteria
() .CreateCriteria("Actors", JoinType.InnerJoin) .Add(Restrictions.Eq("Actor", actorName)) .List
();

  我们再一次对movies进行查询,但是在这个示例中,我们基于一个子集合来进行查询.我们想得到Morgan Freeman的所有movies.依据我们的模型,返回所有对应的ActorRole对象中Actor为Morgan Freeman的movies.

  代码第二行,基于Movie的Actors集合,在Movies和ActorRoles上设置了一个inner join查询.在SQL中inner join查询只返回匹配的行.CreateCriteria可以改变从Movie到ActorRole的查询结果,这使得我们可以进一步筛选ActorRoles(在代码第三行) .
  代码第三行,我们只是筛选ActorRole对象,直至只有Morgan Freeman的角色.由于是inner join查询,同样也会筛选Movies.最后执行该查询并调用List<Movie>得到结果.
  在Microsoft SQL Server中, 生成的SQL语句如下:

View Code
SELECT this_.Id            as Id1_1_,       this_.Version       as Version1_1_,       this_.Name          as Name1_1_,       this_.Description   as Descript5_1_1_,       this_.UnitPrice     as UnitPrice1_1_,       this_.Director      as Director1_1_,       actorrole1_.Id      as Id0_0_,       actorrole1_.Version as Version0_0_,       actorrole1_.Actor   as Actor0_0_,       actorrole1_.Role    as Role0_0_FROM   Product this_       inner join ActorRole actorrole1_         on this_.Id = actorrole1_.MovieIdWHERE  this_.ProductType = 'Eg.Core.Movie'       AND actorrole1_.Actor = 'Morgan Freeman' /* @p0 */
  • GetBookByISBN 查询
View Code
_session.CreateCriteria
() .Add(Restrictions.Eq("ISBN", isbn)) .UniqueResult
();

  在这个条件查询中,通过ISBN来查询特定的book.由于使用UniqueResult<Book>替代了List<Book>,NHibernate将返回一个单独的Book对象,如果查询结果为空,将返回null.该查询假的ISBN是唯一的.

  在Microsoft SQL Server中, 生成的SQL语句如下:

View Code
SELECT this_.Id          as Id1_0_,       this_.Name        as Name1_0_,       this_.Description as Descript4_1_0_,       this_.UnitPrice   as UnitPrice1_0_,       this_.Author      as Author1_0_,       this_.ISBN        as ISBN1_0_FROM   Product this_WHERE  this_.ProductType = 'Eg.Core.Book'       AND this_.ISBN = '3043' /* @p0 */
  • GetProductByPrice 查询
View Code
_session.CreateCriteria
() .Add(Restrictions.And( Restrictions.Ge("UnitPrice", minPrice), Restrictions.Le("UnitPrice", maxPrice) )) .AddOrder(Order.Asc("UnitPrice")) .List
()

  使用这个条件查询,使用一个And操作符将大于等于操作和小于等于操作结合起来,以返回在定价在两个值之间的产品.And约束需要两个子约束作为参数.也可以使用Between约束来达到相同的目的,代码如下:

.Add(Restrictions.Between("UnitPrice", minPrice, maxPrice))

  使用AddOrder方法,按照单价对product结果进行升序排序.

  在Microsoft SQL Server中, 生成的SQL语句如下:

 

View Code
SELECT   this_.Id          as Id1_0_,         this_.Name        as Name1_0_,         this_.Description as Descript4_1_0_,         this_.UnitPrice   as UnitPrice1_0_,         this_.Director    as Director1_0_,         this_.Author      as Author1_0_,         this_.ISBN        as ISBN1_0_,         this_.ProductType as ProductT2_1_0_     FROM     Product this_WHERE    (this_.UnitPrice >= 0 /* @p0 */          and this_.UnitPrice <= 15 /* @p1 */)ORDER BY this_.UnitPrice asc

扩展

  这些条件API是为了动态的创建查询,就像我们在许多零售网站上看到的高级搜索功能.这些网站上,用户可以选择任意数量的筛选和排序条件.然而,这些查询必须动态解析和编译.

  相对于使用一组参数的静态查询,使用命名HQL查询将更好,因为她会在我们创建会话工厂的时候预编译
  这些条件API存在"魔法字符串"的问题,在这些字符串涉及到程序中属性和类的地方.通过使用Visual Studio的重构工具或者ReSharper,我们可以使用强类型来轻松改变属性的名字. 使用这些条件API时,如果我们变更了模型中的一个属性名,那我们将必须更新所有使用该属性的所有条件查询.但是,在下一小节中,新的QueryOver API将解决该问题.

转载于:https://www.cnblogs.com/carfieldSE/archive/2012/07/25/2606819.html

你可能感兴趣的文章
转iOS UIAppearance使用详解
查看>>
winform中实现label的自动换行
查看>>
MFC .。。CReBar 上添加工具栏背景
查看>>
人工智能浪潮下,岗位及就业,技术分析 _证券交易员
查看>>
hdu5705
查看>>
html学习文档-10、HTML 表格
查看>>
Node.js基本开发流程
查看>>
Malware Sample Sources for Researchers
查看>>
[fw]Die 為什麼不能用現在完成式?
查看>>
js弹出框、对话框、提示框、弹窗总结
查看>>
以实现MongoDB副本集状态的监控为例,看Telegraf系统中Exec输入插件如何编写部署...
查看>>
dpkg
查看>>
DHCP概念及其缺点
查看>>
Unity3D中的第三人称镜头的脚本控制
查看>>
nyoj 492
查看>>
jquery.autocomplete插件完美应用
查看>>
RT-Thread Mini2440串口驱动
查看>>
BA--干球温度、露点温度和湿球温度--概念
查看>>
Github泄露扫描系统
查看>>
关于AFNetworking的Assertion failure崩溃
查看>>