Ensure that dynamic LINQ expressions for filters match with those generated by Queryable.Where (#22)

This commit is contained in:
Daniel Macko 2018-05-24 14:16:10 +10:00
parent 56cdb2bf6e
commit fd4367cf37

View File

@ -127,10 +127,12 @@ namespace Sieve.Services
var converter = TypeDescriptor.GetConverter(property.PropertyType); var converter = TypeDescriptor.GetConverter(property.PropertyType);
var parameter = Expression.Parameter(typeof(TEntity), "e"); var parameter = Expression.Parameter(typeof(TEntity), "e");
dynamic filterValue = Expression.Constant(
converter.CanConvertFrom(typeof(string)) ? dynamic constantVal = converter.CanConvertFrom(typeof(string))
converter.ConvertFrom(filterTerm.Value) : ? converter.ConvertFrom(filterTerm.Value)
Convert.ChangeType(filterTerm.Value, property.PropertyType)); : Convert.ChangeType(filterTerm.Value, property.PropertyType);
Expression filterValue = GetClosureOverConstant(constantVal);
dynamic propertyValue = Expression.PropertyOrField(parameter, property.Name); dynamic propertyValue = Expression.PropertyOrField(parameter, property.Name);
@ -201,6 +203,14 @@ namespace Sieve.Services
return result; return result;
} }
//Workaround to ensure that the filter value gets passed as a parameter in generated SQL from EF Core
//See https://github.com/aspnet/EntityFrameworkCore/issues/3361
private Expression GetClosureOverConstant<T>(T constant)
{
Expression<Func<T>> closure = () => constant;
return closure.Body;
}
private IQueryable<TEntity> ApplySorting<TEntity>( private IQueryable<TEntity> ApplySorting<TEntity>(
ISieveModel<IFilterTerm, ISortTerm> model, ISieveModel<IFilterTerm, ISortTerm> model,
IQueryable<TEntity> result, IQueryable<TEntity> result,