本文共 3771 字,大约阅读时间需要 12 分钟。
最近在配置NHibernate实体时遇到了不少问题,今天这篇则主要介绍的是对NHibernate的查询封装相关的问题。NHibernate到目前的3.0版本已经有了几种查询方式,比如:Get、Query、HQL、Criteria,实际使用的过程中可以根据需求选择其中一种或多种方式进行查询。在项目开发过程中,通常会对NHibernate进行一些简单的封装。
今天主要想说的是对查询封装的问题。前段时间一直在研究如何实现类似LINQ的效果,经过网上资料查找和尝试,找到了2种方法,现在记录一下。
这个查询封装是我在CodePlex中无意中看到的,具体项目地址:(注:此处已去除具体链接)。这个项目是《NHibernate with ASP.net Problem-Design-Solution》一书中贯穿讲解NHibernate的,其中对于查询的封装做得很好,使用起来也很方便。原版代码是VB.NET的,我这里附上C#版本的,主要步骤如下:
建立实体类CriteriaParameter用来包装查询参数
代码如下:public class CriteriaParameter{ private string _property; private object _value; private CriteriaOperator _operator; public CriteriaParameter(string propertyName, object value, CriteriaOperator @operator) { _property = propertyName; _value = value; _operator = @operator; } public string PropertyName { get; set; } public object Value { get; set; } public CriteriaOperator CriteriaOperator { get; set; }}这个类主要有3个属性:PropertyName(属性名称)、Value(属性值)以及CriteriaOperator(操作符号枚举)。具体枚举代码如下:
public enum CriteriaOperator{ Like = 1, Equals = 2}枚举目前仅有2个,Like 和 Equals,实际运用的过程中可以根据需求自己添加相应的操作符号,比如Gt(大于)、Lt(小于)等等。
具体的查询封装代码
代码如下:public virtual IListFindBy(List query){ using (_session = NHibernateHelper.GetCurrentSession()) { var criteria = _session.CreateCriteria ().SetCriteriaGroup(); foreach (var item in query) { switch (item.CriteriaOperator) { case CriteriaOperator.Equals: criteria.Add(NHibernate.Criterion.Expression.Eq(item.PropertyName, item.Value)); break; case CriteriaOperator.Like: criteria.Add(NHibernate.Criterion.Expression.Like(item.PropertyName, String.Format("{0}%", item.Value))); break; default: break; } } return criteria.List ().ToList(); }}
这个方法主要接收1个参数,类型为CriteriaParameter的泛型列表,其内部主要是根据具体的操作符号然后拼接相应的表达式。调用代码如下:
public void SelectByLikeName(string name){ var list = studentService.FindBy(new List () { new CriteriaParameter("Name", name, CriteriaOperator.Like) });} 总的来说,这种封装方式还是很方便的,只需创建一个列表,然后再创建CriteriaParameter类并将其添加到列表中就可以了。不过相比3.0版本的LINQ来说,这种封装要逊色不少,这种适合3.0以下的查询。
Nhibernate在3.0正式支持LINQ了,提供了独立LINQ Provider,为我们开发者做查询节省了很大的功夫。我们实际的查询封装只需以下几行代码:
public virtual IListFindBy(Func expression){ using (_session = NHibernateHelper.GetCurrentSession()) { IList list = _session.Query () .Where(expression) .ToList(); return list; }}
将Func<T, bool>作为参数传入Where方法中即可。调用代码如下:
public void SelectByName(string name){ var list = studentService.FindBy((obj) => obj.Name == name);} 这种方法使用起来相当方便,利用lambda表达式,可以很方便地写出所需的查询。相比上一种查询封装更加简洁,更加优雅。
在实际项目中,我也经历了许多问题和挑战。这些问题主要集中在以下几个方面:
以上就是我在实际项目中对NHibernate查询封装的探索和实践总结。通过这些实践,我逐渐掌握了NHibernate的查询封装方法,并也积累了许多在实际项目中遇到的问题和解决方法。
转载地址:http://pqhfk.baihongyu.com/