zoukankan      html  css  js  c++  java
  • ORM篇——有关NHibernate查询封装

      前篇文章记录了我在配置NHibernate实体所遇到的一些问题,今天这篇则主要介绍的是对NHibernate的查询封装相关的问题。

           NHibernate到目前的3.0版本已经有了几种查询方式,比如:Get、Query、HQL、Criteria,实际使用的过程中可以根据需求选择其中1种或多种方式进行查询,对于许多项目开发过程中总会对项目进行一些抽象封装,采用NHibernate进行开发的话,大部分应该都会对Nhibernate进行一些简单的封装,如下图:

          pic103

    基本的增删改我就不说了,今天主要想说的是对查询封装,也是我前段时间一直纠结的问题。

    我想要的查询封装其实很简单,就是可以可以通过表达式进行数据查询,类似于LINQ的效果,后来网上找了点资料,加上自己试验了下找到了2个方法,现在记录一下:

    一、通过Criteria进行查询

         这个查询封装是我在CodePlex中无意中看到的,具体的项目地址:点我进入,这个项目是《NHibernate with ASP.net Problem-Design-Solution》一书中贯穿讲解NHibernate的,其中对于查询的封装做的很好,而且使用起来也很方便,原版代码是VB.NET的,我这边附上C#版本的,主要步骤如下:

    1、建立实体类CriteriaParameter用来包装作为参数传递的表达式,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    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 { return _property; }
            set { _property = value; }
        }
     
        public object Value
        {
            get { return _value; }
            set { _value = value; }
        }
     
        public CriteriaOperator CriteriaOperator
        {
            get { return _operator; }
            set { _operator = value; }
        }
     
    }

    这个类主要有3个属性:PropertyName-属性名称,Value-属性值以及CriteriaOperator-操作符号枚举,具体枚举代码如下:

    1
    2
    3
    4
    5
    6
    public enum CriteriaOperator
    {
     
        Like = 1,
        Equals = 2
    }

    这个枚举目前仅有2个,like和equals,实际运用的过程中可以根据需求自己添加相应的操作符号,比如Gt(大于),Lt(小与)等等。

    接下来是具体的查询封装代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public virtual IList<T> FindBy(List<CriteriaParameter> query)
    {
        using (_session = NHibernateHelper.GetCurrentSession())
        {
            var criteria = _session.CreateCriteria<T>();
            //遍历查询条件,根据操作符号添加相应的表达式
            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<T>();
        }
    }

    这个方法主要接收1个参数,类型为CriteriaParameter的泛型列表,其内部主要是根据具体的操作符号然后拼接相应的表达式,调用代码如下:

    1
    2
    3
    4
    5
    6
    public void SelectByLikeName(string name)
    {
        var list = studentService.FindBy(new List<Common.CriteriaParameter>() {
            new Common.CriteriaParameter("Name", name, Common.CriteriaOperator.Like)
        });
    }

    总的来说还是很方便的,只需创建个列表,然后再创建CriteriaParameter类并将其添加到列表中就可以了,不过相比3.0的LINQ来说这种封装要逊色不少,这种适合3.0以下的查询。

    二、LINQ查询封装

         Nhibernate在3.0正式开始支持LINQ了,提供了独立LINQ Provider,为我们开发者做查询节省了很大的功夫,我们实际的查询封装只需以下几行代码既可:

    1
    2
    3
    4
    5
    6
    7
    8
    public virtual IList<T> FindBy(Func<T, bool> expression)
    {
        using (_session = NHibernateHelper.GetCurrentSession())
        {
            IList<T> list = _session.Query<T>().Where(expression).ToList();
            return list;
        }
    }

    将Func<T, bool>作为参数传入where方法中即可,调用代码如下:

    1
    2
    3
    4
    public void SelectByName(string name)
    {
        var list = studentService.FindBy((obj) => obj.Name == name);
    }

    使用起来相当的方便,利用lambda表达式,可以很方便的写出所需的查询,相比上一种查询封装更加简洁,更加优雅。

  • 相关阅读:
    再谈ORACLE CPROCD进程
    fopen()函数
    Java抓取网页数据(原网页+Javascript返回数据)
    Vmware ESX 5.0 安装与部署
    PostgreSQL服务端监听设置及client连接方法
    方向梯度直方图(HOG)和颜色直方图的一些比較
    Vim简明教程【CoolShell】
    FileSystemWatcher使用方法具体解释
    几种常见模式识别算法整理和总结
    ThreadPool.QueueUserWorkItem的性能问题
  • 原文地址:https://www.cnblogs.com/zemax/p/5175178.html
Copyright © 2011-2022 走看看