问题描述
我正在尝试使用泛型函数过滤类的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
函数的类中添加此代码
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;
}