.NET Core Expression DbFunctions DiffDays - PullRequest
1 голос
/ 04 октября 2019

У меня есть расширение, которое я написал для фильтра даты, используя метод DiffDays с .NET. В .NET Core EF.Functions был заменен на DbFunctions, поэтому он не мог его выполнить.

Мой код .NET

 private static (ParameterExpression param, MemberExpression prop) QueryExpressions<Entity>(IQueryable<Entity> query, string property)
        {
            var param = Expression.Parameter(query.ElementType, "x");
            MemberExpression prop;

            if (property.Contains('.'))
            {
                string[] childProperties = property.Split('.');

                prop = Expression.Property(param, childProperties[0]);

                for (int i = 1; i < childProperties.Length; i++)
                    prop = Expression.Property(prop, childProperties[i]);
            }
            else
                prop = Expression.Property(param, property);

            return (param, prop);
        }

 public static IQueryable<Entity> DiffDaysLessThan<Entity>(this IQueryable<Entity> query, string property, object value)
        {
            var methodInfo = typeof(DbFunctions).GetMethod("DiffDays", new Type[] { typeof(DateTime?), typeof(DateTime?) });

            (ParameterExpression param, MemberExpression prop) = QueryExpressions(query, property);

            var left = Expression.Call(
                methodInfo,
                Expression.Convert(Expression.Constant(value), typeof(DateTime?)), Expression.Convert(prop, typeof(DateTime?)));
            var right = Expression.Convert(Expression.Constant(0), typeof(int?));

            var body = Expression.LessThanOrEqual(left, right);

            return query.Where(Expression.Lambda<Func<Entity, bool>>(body, param));
        }

.NET CORE

   public static IQueryable<Entity> DiffDaysLessThan<Entity>(this IQueryable<Entity> query, string property, object value)
        {

            var methodInfo = typeof(SqlServerDbFunctionsExtensions).GetMethod("DateDiffSecond", new Type[] { typeof(DbFunctions), typeof(DateTime?), typeof(DateTime?) });

            (ParameterExpression param, MemberExpression prop) = QueryExpressions(query, property);

            var left = Expression.Call(
                methodInfo,
                Expression.Convert(Expression.Constant(value), typeof(DateTime?)), Expression.Convert(prop, typeof(DateTime?)));
            var right = Expression.Convert(Expression.Constant(0), typeof(int?));

            var body = Expression.LessThanOrEqual(left, right);

            return query.Where(Expression.Lambda<Func<Entity, bool>>(body, param));
        }

Не удалось получить равный параметру typeof (DbFunctions) на стороне Expression.Call при вызове метода.

ОШИБКА

System.ArgumentException: неверное количество аргументов, предоставленных для вызова метода 'System.Nullable 1[System.Int32] DateDiffSecond(Microsoft.EntityFrameworkCore.DbFunctions, System.Nullable 1 [System.DateTime], System.Nullable`1 [System.DateTime])' (параметр 'method')

1 Ответ

1 голос
/ 04 октября 2019

EF Основные функции: расширение методы класса DbFunctions, возвращаемые свойством EF.Functions. Поэтому, хотя они не используются, вы должны передать первый аргумент типа DbFunctions при их вызове, например,

var left = Expression.Call(
    methodInfo,
    Expression.Constant(EF.Functions, typeof(DbFunctions)), // <--
    Expression.Convert(Expression.Constant(value), typeof(DateTime?)),
    Expression.Convert(prop, typeof(DateTime?)));
...