使用通用 lambda 表达式过滤 IQueryable
Filter IQueryable with generic lambda Expression
我正在尝试使用通用函数过滤 类 的 DateTime?
字段。但是我得到了错误 "The LINQ expression could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()."
我也不知道怎么回事。
这是我的扩展函数:
public static IQueryable<TEntity>? FilterDateField<TEntity>(this IQueryable<TEntity> entities, Expression<Func<TEntity, DateTime?>> dbField, DateTime dateField)
{
var t1 = entities.Where(e=>dbField.Compile().Invoke(e).HasValue && dbField.Compile().Invoke(e)== dateField);
return t1;
}
我从这里的另一个问题得到答案:Generic Linq to Entities filter method that accepts filter criteria and properties to be filtered
只是在拥有 FilterDateField
功能的 class 中添加此代码
public static Expression<Func<TFirstParam, TResult>> Compose<TFirstParam, TIntermediate, TResult>(
this Expression<Func<TFirstParam, TIntermediate>> first, Expression<Func<TIntermediate, TResult>> second)
{
var param = Expression.Parameter(typeof(TFirstParam), "param");
var newFirst = first.Body.Replace(first.Parameters[0], param);
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}
public static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
他们这样使用 de Compose:
public static IQueryable<TEntity>? FilterDateField<TEntity>(this IQueryable<TEntity> entities, Expression<Func<TEntity, DateTime?>> dbField, DateTime dateField)
{
var dateHasValue = dbField.Compose(value => value.HasValue);
var t1 = entities.Where(dateHasValue);
return t1;
}
我正在尝试使用通用函数过滤 类 的 DateTime?
字段。但是我得到了错误 "The LINQ expression could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync()."
我也不知道怎么回事。
这是我的扩展函数:
public static IQueryable<TEntity>? FilterDateField<TEntity>(this IQueryable<TEntity> entities, Expression<Func<TEntity, DateTime?>> dbField, DateTime dateField)
{
var t1 = entities.Where(e=>dbField.Compile().Invoke(e).HasValue && dbField.Compile().Invoke(e)== dateField);
return t1;
}
我从这里的另一个问题得到答案:Generic Linq to Entities filter method that accepts filter criteria and properties to be filtered
只是在拥有 FilterDateField
功能的 class 中添加此代码
public static Expression<Func<TFirstParam, TResult>> Compose<TFirstParam, TIntermediate, TResult>(
this Expression<Func<TFirstParam, TIntermediate>> first, Expression<Func<TIntermediate, TResult>> second)
{
var param = Expression.Parameter(typeof(TFirstParam), "param");
var newFirst = first.Body.Replace(first.Parameters[0], param);
var newSecond = second.Body.Replace(second.Parameters[0], newFirst);
return Expression.Lambda<Func<TFirstParam, TResult>>(newSecond, param);
}
public static Expression Replace(this Expression expression, Expression searchEx, Expression replaceEx)
{
return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public ReplaceVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
他们这样使用 de Compose:
public static IQueryable<TEntity>? FilterDateField<TEntity>(this IQueryable<TEntity> entities, Expression<Func<TEntity, DateTime?>> dbField, DateTime dateField)
{
var dateHasValue = dbField.Compose(value => value.HasValue);
var t1 = entities.Where(dateHasValue);
return t1;
}