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.Nullable
1[System.Int32] DateDiffSecond(Microsoft.EntityFrameworkCore.DbFunctions, System.Nullable
1[System.DateTime], System.Nullable`1[System.DateTime])' (Parameter 'method')
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?)));