我需要在动态EF过滤器生成中调用EntityFunctions方法。如何?

时间:2015-07-15 19:25:28

标签: c# linq entity-framework datetime

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

0 个答案:

没有答案