什么是linq to NHibernate

什么是linq to NHibernate?说简单一点就是linq + NHibernate。

linq语句是.Net 3.5中新增的功能,从问世以来就博得了广大码农的爱好。有了linq,查询变得更方便了。

NHibernate大家也都知道的,一个ORM框架,从java的Hibernate移植过来。用于数据的持久化。

那么linq to NHibernate的目的就是像使用linq一样来查询数据库。

比如,数据库中表tb_User对应实体User。那么我们想查询用户名为”奥特曼”的用户。首先,假设有一个集合IList<User>,我们要查询出用户名为“奥特曼”的用户,linq语句大家都会写:

var user=list.Where(u=>u.Name==”奥特曼”);

语法很简洁,也很优美。如果可以想上面使用linq语句来查询数据库中的数据就好了。。于是,linq to NHibernate就产生了。linq to NHibernate是微软和开源社区优秀开发者的杰作。使得我们查询数据库更加方便了,把广大码农从select * from Table Where语句中解放出来了。当然,linq 不是万能的,但是大部分场景下使用linq to NHbernate是适用的。

linq toNhibernate和 NHibernate内置的几种查询api比较

NHibernate内置了3种查询api:原生sql查询,hql和条件查询(creteria查询)。

假设目前需要查询这样的数据:

user表中的,姓”王“的,男性,年龄在30以上的,且用户的部门是属于”IT“这个bu的员工。并且要求分页显示,每页20条数据,显示第5页。且按照注册时间降序排序。

其中用户的姓名,性别,年龄,注册时间是在user表中的。用户的部门是另一张表。部门表中有个bu字段,可能是”IT,HR“等。

既然使用了NHibernate,我们的表是和实体类做了映射的。

先来看下使用我自己写的一个简单的工具类(下面有给出)是怎么实现的吧:

NHibernateQueryHandler<User> queryHandler=new NHibernateQueryHandler<User>();

queryHandler.AddCriteria(m=>m.Name.StartWith(“王”));

queryHandler.AddCriteria(m=>m.Age>30);

queryHandler.AddCriteria(m=>m.Gender==Gender.Male);

queryHandler.AddCriteria(m=>m.Department.BU==BU.IT);

queryHandler.PageSize=20;

queryHandler.PageIndex=5;

queryHandler.OrderByDesc(m=>m.RegisterTime);

IList<User> users=queryHandler.GetList();

int Count=queryHandler.GetCount();

代码很简单,也很清晰。GetList()方法返回了第5页的20条数据,GetCount返回了中共的数量,这个数据用于前台页面显示分页控件。

大家也都用过NHibernate自带的3种查询,都没有这种类似linq的语法简单和可读性强。

自己写的一个工具类

下面是自己写的一个工具类,在上面的代码中已经使用过了。

public class NHibernateQueryHandler<T>
{
private readonly ISession _session = DependencyResolver.Resolve<ISessionManager>().OpenSession();
private readonly IList<Expression<Func<T, bool>>> _criterialList; private IQueryable<T> _query; private int _pageIndex = 1;
private int _pageSize = int.MaxValue; public NHibernateQueryHandler()
{
_criterialList = new List<Expression<Func<T, bool>>>();
_query = from item in _session.Linq<T>()
select item;
} /// <summary>
/// 添加Where条件
/// </summary>
/// <param name="lambdaFunc"></param>
/// <returns></returns>
public NHibernateQueryHandler<T> AddCriteria(Expression<Func<T, bool>> lambdaFunc)
{
_criterialList.Add(lambdaFunc);
return this;
} /// <summary>
/// 返回数据列表
/// </summary>
/// <returns></returns>
public IList<T> GetList()
{
foreach (var criterion in _criterialList)
{
_query = _query.Where(criterion);
} _query = _query.Skip((_pageIndex - 1) * _pageSize).Take(_pageSize); return _query.ToList();
} /// <summary>
/// 设置分页的页码
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public NHibernateQueryHandler<T> SetPageIndex(int index)
{
_pageIndex = index;
return this;
} /// <summary>
/// 设置分页的页面大小
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
public NHibernateQueryHandler<T> SetPageSize(int size)
{
_pageSize = size;
return this;
} /// <summary>
/// 计算返回的数据数量
/// </summary>
/// <returns></returns>
public int GetCount()
{
foreach (var criterion in _criterialList)
{
_query = _query.Where(criterion);
}
return _query.Count();
} /// <summary>
/// 升序(ASC)排序
/// </summary>
/// <param name="keySlec"></param>
/// <returns></returns>
public NHibernateQueryHandler<T> OrderBy(Expression<Func<T, object>> keySlec)
{
_query = _query.OrderBy(keySlec); return this;
} /// <summary>
/// 降序(DESC)排序
/// </summary>
/// <param name="keySlec"></param>
/// <returns></returns>
public NHibernateQueryHandler<T> OrderByDesc(Expression<Func<T, object>> keySlec)
{
_query = _query.OrderByDescending(keySlec);
return this;
} }

相关API

处理可空类型

如果一个时间的类型是可空的:DateTime?,那么在查询的时候需要注意下。

直接使用query.Select(date=>date==new DataTime(2013,11,11)).而不要使用query.Select(date=>date.Value==new DataTime(2013,11,11))

[Test]
public void Test001()
{
NHibernateQueryHandler<Vacation> queryHandler = new NHibernateQueryHandler<Vacation>();
queryHandler.AddCriteria(m => m.EndTime != null);
//you will get an error: could not resolve property: EndTime.Value of: HelloWorld.Model.Vacation
//queryHandler.AddCriteria(m => m.EndTime.Value == DateTime.Now.Date);
queryHandler.AddCriteria(m => m.EndTime == DateTime.Now.Date);
var list= queryHandler.GetList();
Console.WriteLine(list.Count);
Console.WriteLine(list[0].ID);
}

关于NHibernate的查询api,可以参见NHibernate.Linq的官方源码中的单元测试部分:

NHibernate.Linq单元测试

注意事项

NHibernate2中没有实现linq查询的功能,但是NHibernate 3中本身就有linq查询的功能,不在需要第三方库来实现linq功能。

注:该NHIbernate.Linq.dll 依赖的NHibernate版本是2.1.2.4000.如果使用的NHibernate版本是2.1.2.4000,可直接使用。如果使用的NHibernate版本比2.1.2.4000低,想使用该dll,需添加以下配置到web.config或app.config中。

<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" />
<bindingRedirect oldVersion="2.1.0.3001" newVersion="2.1.2.4000" />
</dependentAssembly>
</assemblyBinding>
</runtime>

下载

下载NHibernate.Linq.dll

最新文章

  1. 你想的到想不到的 javascript 应用小技巧方法
  2. DB2 SQL 日期函数
  3. java String 详解
  4. 一年成为emacs高手
  5. M4: 使用CommandBar
  6. 译:在C#中使用LINQ To SQL
  7. C#开发规范总结(个人建议)
  8. 说反话(c++实现)
  9. Oracle corrupt block(坏块) 详解
  10. java eclise的配置
  11. Linux上构建一个RADIUS服务器详解
  12. Wpf解决TextBox文件拖入问题、拖放问题
  13. USB2.0的基本学习
  14. 潜在语义分析Latent semantic analysis note(LSA)原理及代码
  15. MYSQLI - mysqli
  16. Ubuntu 16.04安装DB2 Express C v11.1
  17. (5)Java数据结构--有继承图,用途分析
  18. js call方法的使用
  19. 企业内知识库wiki所存在的问题
  20. poj3281网络流之最大流

热门文章

  1. C# 一个WCF简单实例
  2. crawler_UE使用技巧
  3. hdu 4915 Parenthese sequence(模拟)2014多培训学校5现场
  4. 在面对变化,撇开NO
  5. linux Packet socket (1)简单介绍
  6. CSS3+HTML5特效3 - 纵向无缝滚动
  7. Asp.net MVC + EF + Spring.Net 项目实践(目录)
  8. IIS7 URL Rewrite 用法实例
  9. POJ 2255 Tree Recovery 二叉树恢复
  10. session什么时候被创建