C# 我需要在动态EF过滤器生成中调用EntityFunctions方法。怎么用?
我们已经实现了一种使用一些反射和其他方法动态创建Lambda过滤器的方法。我最想要的是工作得漂亮。问题是当涉及DateTime值和相等/大于/小于筛选器时 我们的SQL server将项目存储为DateTime对象,有时会为特定项目指定时间。但是,在web上显示列表时,我们只显示日期。因此,当用户(使用剑道网格)尝试将数据过滤到大于或类似日期时,它使用的参数是午夜。这意味着当天午夜后发生的所有事件都包含在不应该包含的范围内。这也意味着当我们使用equals语句时,不会返回任何内容,因为在午夜发生的事情很少 我的研究(使用堆栈溢出)导致我使用C# 我需要在动态EF过滤器生成中调用EntityFunctions方法。怎么用?,c#,linq,entity-framework,datetime,C#,Linq,Entity Framework,Datetime,我们已经实现了一种使用一些反射和其他方法动态创建Lambda过滤器的方法。我最想要的是工作得漂亮。问题是当涉及DateTime值和相等/大于/小于筛选器时 我们的SQL server将项目存储为DateTime对象,有时会为特定项目指定时间。但是,在web上显示列表时,我们只显示日期。因此,当用户(使用剑道网格)尝试将数据过滤到大于或类似日期时,它使用的参数是午夜。这意味着当天午夜后发生的所有事件都包含在不应该包含的范围内。这也意味着当我们使用equals语句时,不会返回任何内容,因为在午夜发生
EntityFunctions.TruncateTime
作为一种方法。我不确定是否要同时对字段和筛选值执行此操作,但我现在甚至无法通过该值
我的第一次尝试是将比较的右侧(值部分)设置为调用EntityFunctions.TruncateTime(filter.value)
。这给了我一个这个函数只能由linq调用到实体错误。进一步的研究让我使用Expression.Call方法,但目前我遇到了一个例外,即类型为“System.Data.Objects.EntityFunctions”的方法“TruncateTime”与提供的参数不兼容。
下面是我尝试拨打电话的代码。我为上下文提供了整个函数。我创建了一个GetPropertyType函数,让我知道是否正在对DateTime字段进行筛选。我还向过滤器对象添加了一个属性,告诉我是否应该忽略时间。如果两者都是真的,那么我才尝试应用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());
}
}
公共静态表达式GetLambdaFilters(ICollection筛选器)
{
如果(filters.Count>0)
{
类型entityType=filters.ElementAt(0).entityType;
var item=Expression.Parameter(entityType,entityType.Name);
表达式leftSide=null;
表达式rightSide=null;
表达式filterExpression=null;
foreach(过滤器中的var过滤器)
{
表达式left=GetPropertyExpression(过滤器,项);
表达式比较=空;
if(左为MethodCallExpression)
{
比较=左;
}
其他的
{
表达式right=null;
如果(!filter.IsCollectionQuery)
{
if(GetPropertyType(filter)=typeof(DateTime)和&filter.IgnoreTime)
{
right=Expression.Call(typeof(EntityFunctions),“TruncateTime”,null,
常量(filter.Value));
}
其他的
{
右=表达式常数(filter.Value);
}
}
其他的
{
Filter innerFilter=新过滤器();
innerFilter.IsCollectionQuery=false;
innerFilter.Operator=filter.Operator;
innerFilter.PropertyName=GetCollectionPropertyName(筛选器,项);
innerFilter.Type=filter.CollectionType;
innerFilter.Value=filter.Value;
List innerfilters=新列表(){
内滤器
};
右=GetLambdaFilters(内部过滤器);
filter.Operator=FilterOperator.Any;
}
比较=GetExpression(左、右、过滤器);
}
if(leftSide==null)
{
左侧=比较;
filterExpression=左侧;
继续;
}
if(rightSide==null)
{
右侧=比较;
filterExpression=Expression.AndAlso(左侧、右侧);
继续;
}
filterExpression=Expression.AndAlso(filterExpression,比较);
}
var func=类型化(func);
函数MakeGenericType(entityType,typeof(bool));
返回表达式.Lambda(funct.MakeGenericType(entityType,typeof(bool)),filterExpression,item);
}
其他的
{
返回GetLambdaFilter(filters.First());
}
}
如果更改行:
right = Expression.Call(typeof (EntityFunctions), "TruncateTime", null,
Expression.Constant(filter.Value));
到
这应该行得通。如果没有导致错误的convert调用,装箱转换部分就不会发生
right = Expression.Call(typeof (EntityFunctions), "TruncateTime", null,
Expression.Convert(Expression.Constant(DateTime.Parse(filter.Value)), typeof(DateTime?)));