我们已经实现了一种使用一些反射和其他方法动态创建Lambda过滤器的方法。我想要的大部分都是精美的工作。问题在于DateTime值和相等/大于/小于过滤器。
我们的SQL服务器将项目存储为DateTime对象,有时为特定项目指定时间。但是,在网络上显示列表时,我们只显示日期。因此,当用户(使用Kendo Grid)尝试将数据过滤到大于或类似的日期时,它将使用午夜作为参数。这意味着当天午夜之后发生的所有物品都包括在内。这也意味着当我们使用equals语句时,不会返回任何内容,因为在午夜恰好发生的情况很少。
我的研究(使用Stack Overflow)让我使用EntityFunctions.TruncateTime
作为方法。我不确定我是否要对字段和过滤值进行处理,但我现在甚至无法超越该值。
我的第一次尝试是将比较的右侧(值部分)设置为对EntityFunctions.TruncateTime(filter.Value)
的调用。这给了我一个This function can only be invoked by linq to entities
错误。进一步的研究使我使用Expression.Call方法,但目前我得到No method 'TruncateTime' on type 'System.Data.Objects.EntityFunctions' is compatible with the supplied arguments.
以下是我尝试拨打电话的代码。我为上下文提供了整个函数。我创建了一个GetPropertyType函数,让我知道我是否在DateTime字段上进行过滤。我还在Filter对象中添加了一个属性,告诉我是否应该忽略时间。如果两者都为真,那么我才尝试应用TruncateTime函数。
我也尝试将DateTime的类型指定为方法中Expression.Constant调用的类型参数,以防万一需要输入,但这也无济于事。
public static Expression GetLambdaFilters(ICollection<Filter> filters)
{
if (filters.Count > 0)
{
Type entityType = filters.ElementAt(0).EntityType;
var item = Expression.Parameter(entityType, entityType.Name);
Expression leftSide = null;
Expression rightSide = null;
Expression filterExpression = null;
foreach (var filter in filters)
{
Expression left = GetPropertyExpression(filter, item);
Expression comparison = null;
if (left is MethodCallExpression)
{
comparison = left;
}
else
{
Expression right = null;
if (!filter.IsCollectionQuery)
{
if (GetPropertyType(filter) == typeof (DateTime) && filter.IgnoreTime)
{
right = Expression.Call(typeof (EntityFunctions), "TruncateTime", null,
Expression.Constant(filter.Value));
}
else
{
right = Expression.Constant(filter.Value);
}
}
else
{
Filter innerFilter = new Filter();
innerFilter.IsCollectionQuery = false;
innerFilter.Operator = filter.Operator;
innerFilter.PropertyName = GetCollectionPropertyName(filter, item);
innerFilter.Type = filter.CollectionType;
innerFilter.Value = filter.Value;
List<Filter> innerfilters = new List<Filter>(){
innerFilter
};
right = GetLambdaFilters(innerfilters);
filter.Operator = FilterOperator.Any;
}
comparison = GetExpression(left, right, filter);
}
if (leftSide == null)
{
leftSide = comparison;
filterExpression = leftSide;
continue;
}
if (rightSide == null)
{
rightSide = comparison;
filterExpression = Expression.AndAlso(leftSide, rightSide);
continue;
}
filterExpression = Expression.AndAlso(filterExpression, comparison);
}
var func = typeof(Func<,>);
func.MakeGenericType(entityType, typeof(bool));
return Expression.Lambda(func.MakeGenericType(entityType, typeof(bool)), filterExpression, item);
}
else
{
return GetLambdaFilter(filters.First());
}
}