QueryOver扩展:如何将成员表达式合并到另一个表达式中
本文关键字:表达式 合并 另一个 成员 扩展 QueryOver | 更新日期: 2023-09-27 17:50:14
我正在尝试对日期时间限制的扩展方法?财产。这是一个搜索查询,我真的不想为所有可能的日期字段重复这段代码。
public static IQueryOver<T, T> WhereInOpenEndedDateRange<T>(this IQueryOver<T, T> query,
Expression<Func<object>> field,
DateTime? rangeFrom,
DateTime? rangeTo)
{
if(rangeFrom.HasValue && rangeTo.HasValue)
{
query.WhereRestrictionOn(field).IsBetween(rangeFrom.Value).And(rangeTo.Value);
}
else if (rangeFrom.HasValue)
{
//query.Where(() => /* help */ >= rangeFrom.Value);
}
else if (rangeTo.HasValue)
{
//query.Where(() => /* help */ <= rangeTo.Value);
}
return query;
}
我想我忽略了表达的一个基本方面。是否有可能通过某种形式的表达式参数,并在/* help */
点使用它?
越来越近,但仍然感觉很遥远…
else if (rangeFrom.HasValue)
{
var lt = Expression.LessThanOrEqual(field, Expression.Constant(rangeFrom, typeof(DateTime?)));
var b = Expression.Lambda<Func<bool>>(lt);
query.Where(b);
}
,但这将不起作用,因为它将比较Func<object>
和DateTime?
。如何将原始属性表达式合并为新的Func<bool>
并保留所需的位以保持NH QueryOver有效?
查看QueryOverRestrictionBuilder的NH源代码后,我将执行
string propertyName = ExpressionProcessor.FindMemberExpression(field.Body)
我不知道怎么用
Expression<Func<bool>>
签名,但这只适用于DateTime?不管怎样,所以我不认为我添加的限制会有什么不同。
基本上,您需要表达式(您的示例中的字段)来精确匹配您发送的参数,即x=>x. somenullabledatefield。'x'是您以
开头的查询类型。session.QueryOver<YourClass>()
,所以它需要包含在要发送的表达式类型中。您还错过了使用
获取参数的机会。ParameterExpression param = expression.Parameters.Single()
用于构造比较表达式。
您正在将BinaryExpression转换为Expression<Func<bool>>
,但您必须进一步将其转换为Expression<Func<T, bool>>
。
public static IQueryOver<T, T> WhereInOpenEndedDateRange<T>(this IQueryOver<T, T> query,
Expression<Func<T, DateTime?>> expression,
DateTime? rangeFrom,
DateTime? rangeTo) where T : class
{
// Lambda being sent in
ParameterExpression param = expression.Parameters.Single();
if(rangeFrom.HasValue && rangeTo.HasValue)
{
// GT Comparison
var expressionGT =
Expression.GreaterThanOrEqual(
expression.Body,
Expression.Constant(rangeFrom.Value, typeof(DateTime?)
)
);
// LT Comparison
var expressionLT =
Expression.LessThanOrEqual(
expression.Body,
Expression.Constant(rangeTo.Value, typeof(DateTime?)
)
);
query.Where(
Expression.Lambda<Func<T, bool>>(expressionGT, param))
.And(
Expression.Lambda<Func<T, bool>>(expressionLT, param)
);
}
else if(rangeFrom.HasValue)
{
// GT Comparison
BinaryExpression expressionGT =
Expression.GreaterThanOrEqual(
expression.Body,
Expression.Constant(rangeFrom.Value, typeof(DateTime?)
)
);
// covert to lambda
query.Where(Expression.Lambda<Func<T, bool>>(expressionGT, param));
}
else if(rangeTo.HasValue)
{
// LT Comparison
BinaryExpression expressionLT =
Expression.LessThanOrEqual(
expression.Body,
Expression.Constant(rangeTo.Value, typeof(DateTime?)
)
);
query.Where(Expression.Lambda<Func<T, bool>>(expressionLT, param));
}
return query;
}
使用var test = session.QueryOver<MyPocoClass>()
.WhereInOpenEndedDateRange(x=>x.SomeNullableDateField, DateTime.Now, null);