linq to NHibernate
什么是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的官方源码中的单元测试部分:
注意事项
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>
下载
linq to NHibernate的更多相关文章
- Linq To Nhibernate 性能优化(入门级)
最近都是在用Nhibernate和数据库打交道,说实话的,我觉得Nhibernate比Ado.Net更好用,但是在对于一些复杂的查询Nhibernate还是比不上Ado.Net.废话不多说了,下面讲讲 ...
- Linq to NHibernate入门示例
Linq to NHibernate入门示例 NHibernate相关: 09-08-25连贯NHibernate正式发布1.0候选版 09-08-17NHibernate中一对一关联的延迟加载 09 ...
- NHibernate 数据查询之Linq to NHibernate
刚学NHibernate的时候觉得,HQL挺好用的,但是终归没有与其他技术相关联,只有NHibernate用到,一来容易忘记,二来没有智能提示,排除错误什么的都不给力,直到看到一个同事用Linq to ...
- 使用NHibernate(5)-- Linq To NHibernate
Linq是NHibernate所支持的查询语言之一,对于Linq的实现在源码的src/Linq目录下.以下是一个使用Linq进行查询数据的示例: var users = session.Query&l ...
- NHibernate系列文章二十四:NHibernate查询之Linq查询(附程序下载)
摘要 NHibernate从3.0开始支持Linq查询.写Linq to NHibernate查询就跟写.net linq代码一样,非常灵活,可以很容易实现复杂的查询.这篇文章使用Linq to NH ...
- NHibernate Linq查询 扩展增强 (第九篇)
在上一篇的Linq to NHibernate的介绍当中,全部是namespace NHibernate命名空间中的IQueryOver<TRoot, TSubType>接口提供的.IQu ...
- 4、ASP.NET MVC入门到精通——NHibernate构建一个ASP.NET MVC应用程序
下周就去办理离职手续了,之前没有使用过NHibernate,只知道NHibernate是一种ORM框架,但是听说新公司是使用NHibernate在做项目,所以,我就网上找资料学习一下NHibernat ...
- [NHibernate]基本配置与测试
目录 写在前面 nhibernate文档 搭建项目 映射文件 持久化类 辅助类 数据库设计与连接配置 测试 总结 写在前面 一年前刚来这家公司,发现项目中使用的ORM是Nhibernate,这个之前确 ...
- NHibernate系列文章目录
第一章:NHibernate基础 NHibernate介绍 第一个NHibernate工程 简单的增删改查询 运行时监控 NHibernate配置 数据类型映射 Get/Load方法 NHiberna ...
随机推荐
- ftp server来源分析20140602
ftp server学习位和源代码分析片 记录自己的第一个开源的分析过程: 从源代码:野狐灯(我接下来的几篇文章是从源头:野狐灯,每个以下哪项不是他们设置.) 20140602 Ftp的源码目录例如 ...
- AppiumDriver java部分api
getAppStrings() 默认系统语言对应的Strings.xml文件内的数据. getAppStrings(String language) 查找某一个语言环境对应的字符串文件Strings. ...
- 【Android UI设计和开发】动画(Animation)详细说明(一)
Android开发之动画效果浅析 请尊重他人的劳动成果.转载请注明出处:Android开发之动画效果浅析 程序执行效果图: Android动画主要包括补间动画(Tween)View Animation ...
- utf8 和 UTF-8 在使用中的差别
在使用中经常遇到utf-8和utf8,如今最终弄明确他们的使用不同之处了,如今来和大家分享一下,以下我们看一下utf8 和 UTF-8 有什么差别 "UTF-8"是标准写法,ph ...
- timesten备份和恢复
ttIsql "DSN=ttwind;UID=cacheuser;PWD=cacheuser;OraclePWD=cacheuser;" --1.查看当前版本号 Command&g ...
- sgu139Help Needed!推断15数码是否有解,以及推断N数码是否有解的推论
是这种,要你推断一个15数码是否有解. 我不会,找了这样一个方法. 将16个数按出现顺序存放在一维数组里面, 然后累加每一个数的逆序对数目, 还要加上0到终态的曼哈顿距离,得到一个数x. 因为最后的状 ...
- C语言编写Windows服务程序
原文:C语言编写Windows服务程序 #include <Windows.h> #include <stdio.h> #define SLEEP_TIME 5000 // 间 ...
- python学习笔记(五岁以下儿童)深深浅浅的副本复印件,文件和文件夹
python学习笔记(五岁以下儿童) 深拷贝-浅拷贝 浅拷贝就是对引用的拷贝(仅仅拷贝父对象) 深拷贝就是对对象的资源拷贝 普通的复制,仅仅是添加了一个指向同一个地址空间的"标签" ...
- [译]内存中的Java数组是怎么样的
(文章翻译自What does a Java array look like in memory?) Java中的数组存储了两个中的一个类型:原始类型的类或则是引用类型(比如指针) 当一个对象通过Ne ...
- AJAX入门——工作原理
同步和异步交互,了解互动 对于一个样本:一般B/S模式(同步) AJAX技术(异步) * 同步: 提交请求->等待server处理->处理完成返回 ...