Using QueryOver
使用QueryOver
步骤
1. 完成本章简介中的通用步骤.
2. 在Queries类中,添加下面的方法:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public IEnumerable<Movie> GetMoviesDirectedBy(string directorName) { return _session.QueryOver<Movie>() .Where(m => m.Director == directorName) .List(); }
3. 在Queries类中,添加下面的方法,该方法通过actor name来查询movies:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public IEnumerable<Movie> GetMoviesWith(string actorName) { return _session.QueryOver<Movie>() .OrderBy(m => m.UnitPrice).Asc .Inner.JoinQueryOver<ActorRole>(m => m.Actors) .Where(a => a.Actor == actorName) .List(); }
4. 在Queries类中,添加下面的方法,该方法通过ISBN来查询book:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public Book GetBookByISBN(string isbn) { return _session.QueryOver<Book>() .Where(b => b.ISBN == isbn) .SingleOrDefault(); }
5. 添加下面的方法,该方法查找一定价格范围内的所有产品:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public IEnumerable<Product> GetProductByPrice( decimal minPrice, decimal maxPrice) { return _session.QueryOver<Product>() .Where(p => p.UnitPrice >= minPrice && p.UnitPrice <= maxPrice) .OrderBy(p => p.UnitPrice).Asc .List(); }
6. 在Program.cs中, 为RunQueries方法添加下述代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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. 编译运行,结果如下图所示:
原理
在上面的代码中,我们使用NHibernate的QueryOver语法实现了上一小节中的查询.使用该语法,大多数的约束条件可以用一个Where方法来表示,该方法使用λ表达式作为输入.例如,为了筛选movies的director的名字,可以使用Where(m => m.Director == directorName). 在许多情况下,可以将多个约束条件合并到一个Where方法中.要查找一定价格范围内的产品,可以使用如下代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
.Where(p => p.UnitPrice >= minPrice)
.And(p => p.UnitPrice <= maxPrice)
也可以将她们合并到一个Where方法中,代码如下:
.Where(p => p.UnitPrice >= minPrice && p.UnitPrice <= maxPrice)
一些约束条件,比如Between,没有等效的λ表达式.对于这些操作,我们开始使用WhereRestrictionOn来指定将要使用的属性.然后接着调用约束的方法.例如,可以使用约束条件中的Between约束写出同样价格范围的约束器:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
.WhereRestrictionOn(p => p.UnitPrice)
.IsBetween(minPrice).And(maxPrice)
要创建join查询,可以使用JoinQueryOver,代码如下:
.Inner.JoinQueryOver<ActorRole>(m => m.Actors)
在QueryOver中,UniqueResult被替换为LINQ样式的SingleOrDefault.
扩展
QueryOver是NHibernate现有条件查询之外的一个新的API.我们应该直接使用条件API,我们可以通过QueryOver的UnderlyingCriteria 属性来进行条件查询.