10分钟搞定Linq to NHibernate(二)——查询篇

有人问过我一个问题,既然用了NHibernate还有必要用Linq吗?就这个问题,我回答下列几点:

  1.Linq to NHibernate有VS的IDE提示,编译器可以帮助我提示出错误。

  2.Linq to NHibernate最大限度的帮我们优化SQL语句,尤其是匿名类的查询语句和聚合函数的查询。

  3.可以结合Linq加NHibernate各自的延迟加载特性,帮我们在必要的时候生成特定的SQL语句。

  4.统一语言,必要的时候不用学习HQL来增加学习成本。

  5.方便于满足复杂查询的需求(如报表)。

然而对上述观点我提出如下建议:

  1.建议映射文件*.hbm.xml文件的lazy="true"来开启延迟加载。

  2.数据库访问对象(Dao)类的返回值建议使用IQueryable<T>泛型类型或者IQueryable接口

 

以下是Linq to NHibernate查询语句的代码。

 

 

 

ContractedBlock.gif ExpandedBlockStart.gif ProductsDao
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Domain.Entities;
using NHibernate;
using NHibernate.Linq;
using System.Linq.Expressions;

namespace Linq2NHibernate.Dao
{
    
public class ProductsDao
    {
        
private ISession session = DBUtility.NHibernateHelper.GetCurrentSession();

        
/// <summary>
        
/// select 语句
        
/// sql : SELECT this_.ProductID as ProductID1_0_, this_.ProductName as ProductN2_1_0_, 
        
/// this_.QuantityPerUnit as Quantity3_1_0_, this_.UnitPrice as UnitPrice1_0_, 
        
/// this_.UnitsInStock as UnitsInS5_1_0_, this_.UnitsOnOrder as UnitsOnO6_1_0_, 
        
/// this_.ReorderLevel as ReorderL7_1_0_, this_.Discontinued as Disconti8_1_0_, 
        
/// this_.CategoryID as CategoryID1_0_ FROM Products this_
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> GetAll()
        {
            var query 
= from s in session.Linq<Products>() select s;
            
return query;
        }

        
/// <summary>
        
/// 匿名类查询
        
/// sql : SELECT this_.ProductID as y0_, this_.ProductName as y1_, 
        
/// this_.QuantityPerUnit as y2_ FROM Products this_
        
/// 个人认为匿名类查询可以优化Nhibernate查询,仅仅生成部分字段的查询
        
/// </summary>
        
/// <returns></returns>
        public IQueryable AnonymousType()
        {
            var query 
= from products in session.Linq<Products>()
                        select 
                        
new { products.ProductID, products.ProductName, products.QuantityPerUnit };
            
return query;
        }

        
/// <summary>
        
/// 查询第一个记录 top 1
        
/// sql : SELECT top 1 this_.ProductID as ProductID1_0_, this_.ProductName as ProductN2_1_0_, 
        
/// this_.QuantityPerUnit as Quantity3_1_0_, this_.UnitPrice as UnitPrice1_0_, 
        
/// this_.UnitsInStock as UnitsInS5_1_0_, this_.UnitsOnOrder as UnitsOnO6_1_0_, 
        
/// this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ FROM Products this_
        
/// </summary>
        
/// <returns></returns>
        public Products First()
        {
            var query 
= from s in session.Linq<Products>() select s;
            
return query.First<Products>();
        }

        
/// <summary>
        
/// Count(*) 聚合函数查询
        
/// sql : SELECT count(*) as y0_ FROM Products this_
        
/// </summary>
        
/// <returns></returns>
        public int Count()
        {
            var query 
= from s in session.Linq<Products>() select s;
            
return query.Count<Products>();
        }
        
        
/// <summary>
        
/// where ProductName = "Ikura" or ProductName = "Konbu" 语句
        
/// sql : exec sp_executesql N'SELECT this_.ProductID as ProductID1_0_, 
        
/// this_.ProductName as ProductN2_1_0_, this_.QuantityPerUnit as Quantity3_1_0_, 
        
/// this_.UnitPrice as UnitPrice1_0_, this_.UnitsInStock as UnitsInS5_1_0_, 
        
/// this_.UnitsOnOrder as UnitsOnO6_1_0_, this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ 
        
/// FROM Products this_ WHERE (this_.ProductName = @p0 or this_.ProductName = @p1)', 
        
/// N'@p0 nvarchar(5),@p1 nvarchar(5)', @p0 = N'Ikura', @p1 = N'Konbu'
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> SelectOr()
        {
            var query 
= from s in session.Linq<Products>() 
                        
where s.ProductName == "Ikura" || s.ProductName == "Konbu" select s;
            
return query;
        }

        
/// <summary>
        
/// where UnitPrice = 21 and UnitsInStock = 15 语句
        
/// sql : exec sp_executesql N'SELECT this_.ProductID as ProductID1_0_, 
        
/// this_.ProductName as ProductN2_1_0_, this_.QuantityPerUnit as Quantity3_1_0_, 
        
/// this_.UnitPrice as UnitPrice1_0_, this_.UnitsInStock as UnitsInS5_1_0_, 
        
/// this_.UnitsOnOrder as UnitsOnO6_1_0_, this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ 
        
/// FROM Products this_ WHERE (this_.UnitPrice = @p0 and this_.UnitsInStock = @p1)', 
        
/// N'@p0 decimal(2,0),@p1 smallint', @p0 = 21, @p1 = 15
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> SelectAnd()
        {
            var query 
= from s in session.Linq<Products>() 
                        
where s.UnitPrice == 21 && s.UnitsInStock == 15 select s;
            
return query;
        }

        
/// <summary>
        
/// where UnitPrice >= 21 语句
        
/// sql : exec sp_executesql N'SELECT this_.ProductID as ProductID1_0_, 
        
/// this_.ProductName as ProductN2_1_0_, this_.QuantityPerUnit as Quantity3_1_0_, 
        
/// this_.UnitPrice as UnitPrice1_0_, this_.UnitsInStock as UnitsInS5_1_0_, 
        
/// this_.UnitsOnOrder as UnitsOnO6_1_0_, this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ 
        
/// FROM Products this_ WHERE this_.UnitPrice >= @p0', N'@p0 decimal(2,0)', @p0 = 21
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> SelectLe()
        {
            var query 
= from s in session.Linq<Products>() 
                        
where s.UnitPrice >= 21  select s;
            
return query;
        }

        
/// <summary>
        
/// where UnitPrice Between 15 and 100 语句
        
/// sql : exec sp_executesql N'SELECT this_.ProductID as ProductID1_0_, 
        
/// this_.ProductName as ProductN2_1_0_, this_.QuantityPerUnit as Quantity3_1_0_, 
        
/// this_.UnitPrice as UnitPrice1_0_, this_.UnitsInStock as UnitsInS5_1_0_, 
        
/// this_.UnitsOnOrder as UnitsOnO6_1_0_, this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ 
        
/// FROM Products this_ WHERE (this_.UnitPrice >= @p0 
        
/// and this_.UnitPrice <= @p1)', N'@p0 decimal(2,0),@p1 decimal(3,0)', @p0 = 15, @p1 = 100
        /// </summary>
        
/// <returns></returns>
        public IQueryable<Products> SelectBetweenAnd()
        {
            var query 
= from s in session.Linq<Products>() 
                        
where s.UnitPrice >= 15 && s.UnitPrice <= 100 select s;
            
return query;
        }

        
/// <summary>
        
/// s.QuantityPerUnit == null : where QuantityPerUnit Is Null 语句
        
/// s.QuantityPerUnit != null : where QuantityPerUnit Is Not Null 语句
        
/// sql : SELECT this_.ProductID as ProductID1_0_, this_.ProductName as ProductN2_1_0_, 
        
/// this_.QuantityPerUnit as Quantity3_1_0_, this_.UnitPrice as UnitPrice1_0_, 
        
/// this_.UnitsInStock as UnitsInS5_1_0_, this_.UnitsOnOrder as UnitsOnO6_1_0_, 
        
/// this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ 
        
/// FROM Products this_ WHERE this_.QuantityPerUnit is null
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> SelectIsNull()
        {
            var query 
= from s in session.Linq<Products>() 
                        
where s.QuantityPerUnit == null select s;
            
return query;
        }

        
/// <summary>
        
/// 动态linq语句
        
/// sql : exec sp_executesql N'SELECT this_.ProductID as ProductID1_0_, 
        
/// this_.ProductName as ProductN2_1_0_, this_.QuantityPerUnit as Quantity3_1_0_, 
        
/// this_.UnitPrice as UnitPrice1_0_, this_.UnitsInStock as UnitsInS5_1_0_, 
        
/// this_.UnitsOnOrder as UnitsOnO6_1_0_, this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ 
        
/// FROM Products this_ WHERE (this_.ProductName = @p0 or this_.ProductName = @p1)', 
        
/// N'@p0 nvarchar(5),@p1 nvarchar(5)', @p0 = N'Ikura', @p1 = N'Konbu'
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> SelectDynamic()
        {
            Expression
<Func<Products, bool>> expr1 = u => u.ProductName == "Ikura";
            Expression
<Func<Products, bool>> expr2 = u => u.ProductName == "Konbu";

            var invokedExpr 
= Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            var dynamicWhereClause 
= Expression.Lambda<Func<Products, bool>>
                  (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);

            var query 
= session.Linq<Products>().Where(dynamicWhereClause);
            
return query;
        }

        
/// <summary>
        
/// StartsWith : ProductName Like "A%" 语句
        
/// EndsWith: ProductName Like "%A" 语句
        
/// Contains: ProductName Like "%A%" 语句
        
/// sql : exec sp_executesql N'SELECT this_.ProductID as ProductID1_0_, 
        
/// this_.ProductName as ProductN2_1_0_, this_.QuantityPerUnit as Quantity3_1_0_, 
        
/// this_.UnitPrice as UnitPrice1_0_, this_.UnitsInStock as UnitsInS5_1_0_, 
        
/// this_.UnitsOnOrder as UnitsOnO6_1_0_, this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ FROM Products this_ 
        
/// WHERE this_.ProductName like @p0', N'@p0 nvarchar(2)', @p0 = N'A%'
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> GetLike()
        {
            var query 
= from p in session.Linq<Products>() 
                        
where p.ProductName.StartsWith("A") select p;
            
return query;
        }

        
/// <summary>
        
/// names.Contains : ProductName In "Tofu,Pavlova" 语句
        
/// !names.Contains : ProductName Not In "Tofu,Pavlova" 语句
        
/// sql : exec sp_executesql N'SELECT this_.ProductID as ProductID1_0_, 
        
/// this_.ProductName as ProductN2_1_0_, this_.QuantityPerUnit as Quantity3_1_0_, 
        
/// this_.UnitPrice as UnitPrice1_0_, this_.UnitsInStock as UnitsInS5_1_0_, 
        
/// this_.UnitsOnOrder as UnitsOnO6_1_0_, this_.ReorderLevel as ReorderL7_1_0_, 
        
/// this_.Discontinued as Disconti8_1_0_, this_.CategoryID as CategoryID1_0_ 
        
/// FROM Products this_ WHERE this_.ProductName in (@p0, @p1)', 
        
/// N'@p0 nvarchar(4),@p1 nvarchar(7)', @p0 = N'Tofu', @p1 = N'Pavlova'
        
/// </summary>
        
/// <returns></returns>
        public IQueryable<Products> GetIn()
        {
            var names 
= new string[] { "Tofu""Pavlova" };
            var query 
= from p in session.Linq<Products>() 
                        
where names.Contains(p.ProductName) select p;
            
return query;
        }
    }
}

 

 

从上述代码,我可以看到Linq to NHibernate查询语句和SQL语句的对照。

 代码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值