Nhibernate.Criterion.Expression 【转】

转载文章,出处不详

四 数据加载

1. Expression

Expression数据加载由ICriteria接口实现, ICriteria在程序中是无法直接构造的,必须通过ISession.CreateCriteria(type)来获得。ICriteria主要负责存储一组Expression对象和一组Order对象,当调用List执行查询时,ICriteria对Expression对象和Order对象进行组合以产生NHB内部的查询语句,然后交由DataLoader(数据加载器)来读取满足条件的记录。

下面列出ICriteria接口中的一些常用方法:

Add:加入条件表达式(Expression对象),此方法可多次调用以组合多个条件;
AddOrder:加入排序的字段(Order对象);
List:执行查询, 返回满足条件的对象集合。
SetMaxResults:设置返回的最大结果数,可用于分页;
SetFirstResult:设置首个对象返回的位置,可用于分页;

通过SetMaxResults和SetFirstResult方法,就可以取得指定范围段的记录,相当于是分页,
!!! 要说明的是,对于SQL Server数据库,它是使用将DataReader指针移到firstResult位置,再读取maxResults记录的方式来实现分页的,在数据量非常大(10w以上)的情况下,性能很难保证。

所有表达式对象都继承之Expression类,这是一个抽象(abstract)类, 同时也是一个类工厂(Factory Method模式), 用于创建派生的Expression对象,这样就隐藏了派生类的细节。(又学到一招了吧!)

下面列出几个常用的Expression对象:

EqExpression :相等判断的表达式, 等同于 propertyName = value,由Expression.Eq取得;
GtExpression :大于判断的表达式, 等同于 propertyName > value,由Expression.Gt取得; 
LikeExpression :相似判断的表达式, 等同于 propertyName like value,由Expression.Like取得;
AndExpression :对两个表达式进行And操作, 等同于 expr1 and expr2,由Expression.And取得; 
OrExpression :对两个表达式进行Or操作, 等同于 expr1 or expr2,由Expression.Or取得;
更多的Expression对象请参考相关文档或源代码。

Order对象用于向ICriteria接口提供排序信息,这个类提供了两个静态方法,分别是Asc和Desc,顾名思义就是创建升序和降序的Order对象,例如要取得一个按更新日期(Updated)降序的Order对象, 使用Order.Desc("Updated")就可以了。

下面以加载Customer数据为例来说明Expression的使用:
测试代码如:

 

using System; using NHibernate.Hql; using NHibernate.Expression; using NHibernate.Type; using NUnit.Framework; using System.Collections; namespace NHibernateTest { ////// CustomerSystemFixture 的摘要说明。 /// [TestFixture] publicclass CustomerSystemFixture { public CustomerSystemFixture() { } [Test] publicvoid LoadByNameTest() { ICriterion crit = Expression.Eq("CompanyName", "company name"); IList custs = ObjectLoader.Find(crit, typeof(Customer)); // 根据期望的结果集写Assertion. } [Test] publicvoid LoadByNamePagerTest() { ICriterion crit = Expression.Eq("CompanyName", "company name"); PagerInfo pi =new PagerInfo(0, 5); IList custs = ObjectLoader.Find(crit, typeof(Customer) , pi); // 根据期望的结果集写Assertion. } [Test] publicvoid LoadByNameAndAddressTest() { ICriterion crit = Expression.Eq("CompanyName", "company name"); ICriterion crit2 = Expression.Eq("Address", "address"); IList custs = ObjectLoader.Find(Expression.And(crit, crit2), typeof(Customer)); // 根据期望的结果集写Assertion. } [Test] publicvoid LoadByNameOrAddressTest() { ICriterion crit = Expression.Eq("CompanyName", "company name"); ICriterion crit2 = Expression.Eq("Address", "address"); IList custs = ObjectLoader.Find(Expression.Or(crit, crit2), typeof(Customer)); // 根据期望的结果集写Assertion. } [Test] publicvoid LoadAllTest () { string query =" from Customer "; IList custs = ObjectLoader.Find( query, null ); // 根据期望的结果集写Assertion. } [Test] publicvoid LoadPagerDataTest() { string query =" from Customer "; PagerInfo pi =new PagerInfo( 0, 5 ); IList custs = ObjectLoader.Find( query, null, pi ); } [Test] publicvoid LoadByName2Test() { IList paramInfos =new ArrayList(); string query =" from Customer c where c.CompanyName = :CompanyName "; paramInfos.Add(new ParamInfo("CompanyName", "test name",TypeFactory.GetStringType()) ); IList custs = ObjectLoader.Find( query, paramInfos ); // 根据期望的结果集写Assertion. } [Test] publicvoid LoadByNameAndAddress2Test() { IList paramInfos =new ArrayList(); string query =" from Customer c where c.CompanyName = :CompanyName and c.Address = :Address"; paramInfos.Add( new ParamInfo("CompanyName", "test name",TypeFactory.GetStringType())); paramInfos.Add( new ParamInfo("Address", "test address",TypeFactory.GetStringType())); IList custs = ObjectLoader.Find( query, paramInfos ); // 根据期望的结果集写Assertion. } } }

             

在上面的代码中,给出了四个较简单的表达式加载的测试用例,它们都通过调用ObjectLoader对象的Find方法来取得数据,ObjectLoader是我们自己的数据加载器,它简单的封装了NHB中的数据加载功能。另外,我们还用一个PagerInfo类封装了分页数据,以方便数据传递。
注意:以前代码是这么写的

[Test]
   public void LoadByNameTest() {
      Expression expr = Expression.Eq( “CompanyName”, “company name” );
      IList custs = ObjectLoader.Find( expr, typeof(Customer) );
      // 根据期望的结果集写Assertion.
   }

对比下现在的写法:
       [Test]
        public void LoadByNameTest() 
        {
            ICriterion crit 
= Expression.Eq("CompanyName""company name");
            IList custs 
= ObjectLoader.Find(crit, typeof(Customer));
            
// 根据期望的结果集写Assertion.
        }

这个应该是NHibernate的版本引起的变化。

posted @ 2011-07-08 17:14  Old  阅读(3192)  评论(1编辑  收藏  举报