.NET Core Expression DbFunctions DiffDays

.net-core-3.0 ef-core-2.2 entity-framework-core linq

Question

I have an extension I have written for the date filter using the DiffDays method with .NET. In .NET Core, EF.Functions was replaced by DbFunctions, so it could not execute it.

My .NET Code

 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));
        }

I could not equals the typeof (DbFunctions) parameter on the Expression.Call side when calling the method.

ERROR

System.ArgumentException: Incorrect number of arguments supplied for call to method 'System.Nullable1[System.Int32] DateDiffSecond(Microsoft.EntityFrameworkCore.DbFunctions, System.Nullable1[System.DateTime], System.Nullable`1[System.DateTime])' (Parameter 'method')

1
1
10/4/2019 12:01:35 PM

Accepted Answer

EF Core functions are extension methods of DbFunctions class returned by EF.Functions property. So although unused, you have to pass the first argument of type DbFunctions when calling them, e.g.

var left = Expression.Call(
    methodInfo,
    Expression.Constant(EF.Functions, typeof(DbFunctions)), // <--
    Expression.Convert(Expression.Constant(value), typeof(DateTime?)),
    Expression.Convert(prop, typeof(DateTime?)));
1
10/4/2019 12:45:58 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow