转载文章,出处不详
四 数据加载
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的版本引起的变化。