Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我需要在动态EF过滤器生成中调用EntityFunctions方法。怎么用?_C#_Linq_Entity Framework_Datetime - Fatal编程技术网

C# 我需要在动态EF过滤器生成中调用EntityFunctions方法。怎么用?

C# 我需要在动态EF过滤器生成中调用EntityFunctions方法。怎么用?,c#,linq,entity-framework,datetime,C#,Linq,Entity Framework,Datetime,我们已经实现了一种使用一些反射和其他方法动态创建Lambda过滤器的方法。我最想要的是工作得漂亮。问题是当涉及DateTime值和相等/大于/小于筛选器时 我们的SQL server将项目存储为DateTime对象,有时会为特定项目指定时间。但是,在web上显示列表时,我们只显示日期。因此,当用户(使用剑道网格)尝试将数据过滤到大于或类似日期时,它使用的参数是午夜。这意味着当天午夜后发生的所有事件都包含在不应该包含的范围内。这也意味着当我们使用equals语句时,不会返回任何内容,因为在午夜发生

我们已经实现了一种使用一些反射和其他方法动态创建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?)));