NHibernate Criteria中的And, Or
public IList < BoxDao > QueryRelated(TemplateDao[] templates, DataSourceDao[] datasources)
{
ICriteria criteria = this ._session.CreateCriteria( typeof (BoxDao));
Expression.ICriterion exp = null ;
exp = Expression.Or(Expression.In( " Template " , templates), Expression.In( " Wrapper " , templates));
exp = Expression.Or(exp, Expression.In( " DataSource " , datasources));
exp = Expression.And(exp, Expression.In( " State " , new EnumState[] { EnumState.Publish, EnumState.Edit }));
criteria.Add(exp);
return criteria.List < BoxDao > ();
}
{
ICriteria criteria = this ._session.CreateCriteria( typeof (BoxDao));
Expression.ICriterion exp = null ;
exp = Expression.Or(Expression.In( " Template " , templates), Expression.In( " Wrapper " , templates));
exp = Expression.Or(exp, Expression.In( " DataSource " , datasources));
exp = Expression.And(exp, Expression.In( " State " , new EnumState[] { EnumState.Publish, EnumState.Edit }));
criteria.Add(exp);
return criteria.List < BoxDao > ();
}
如果参数templates、datasources都不为null,执行的SQL如下
SELECT
...
FROM CMS_BOX this_
WHERE ((this_.TEMP_ID in (?p0) or this_.WRAPPER_ID in (?p1)) or this_.DS_ID in (?p2)) and this_.BOX_STATE in (?p3, ?p4)
FROM CMS_BOX this_
WHERE ((this_.TEMP_ID in (?p0) or this_.WRAPPER_ID in (?p1)) or this_.DS_ID in (?p2)) and this_.BOX_STATE in (?p3, ?p4)
假如templates为null,执行的SQL如下
SELECT
...
FROM CMS_BOX this_
WHERE (( 1 = 0 or 1 = 0 ) or this_.DS_ID in (?p0)) and this_.BOX_STATE in (?p1, ?p2, ?p3)
FROM CMS_BOX this_
WHERE (( 1 = 0 or 1 = 0 ) or this_.DS_ID in (?p0)) and this_.BOX_STATE in (?p1, ?p2, ?p3)
对这种组合的And、Or条件,一开始担心null值会引起NHibernate的异常,所以自己判断参数是否为null来确定怎样使用And、Or,写出来的代码很复杂,测试一下发现NHibernate能够处理数组为null的异常情况,因此代码简单多了。
可以看到,当数组为null时,NHibernate使用一个1=0的表达式,这正是我要的效果,因此可以省略null判断,否则还是需要自己处理的。
可以使用HQL,不过HQL不支持null参数,参数的个数为0也不行。
public
IList
<
BoxDao
>
QueryRelated(IList
<
TemplateDao
>
templates, IList
<
DataSourceDao
>
datasources)
{
IList < EnumState > states = new List < EnumState > ( 2 );
states.Add(EnumState.Publish);
states.Add(EnumState.Edit);
return this ._session.CreateQuery( @" from BoxDao p
where (p.Template in :templates or p.Wrapper in :templates or p.DataSource in :datasources) and p.State in :states " )
.SetParameterList( " templates " , templates)
.SetParameterList( " datasources " , datasources)
.SetParameterList( " states " , states)
.List < BoxDao > ();
}
{
IList < EnumState > states = new List < EnumState > ( 2 );
states.Add(EnumState.Publish);
states.Add(EnumState.Edit);
return this ._session.CreateQuery( @" from BoxDao p
where (p.Template in :templates or p.Wrapper in :templates or p.DataSource in :datasources) and p.State in :states " )
.SetParameterList( " templates " , templates)
.SetParameterList( " datasources " , datasources)
.SetParameterList( " states " , states)
.List < BoxDao > ();
}