我在ASP.NET Core项目中使用Syncfusion的Grid组件。在对网格视图进行排序,过滤和分页时,它将对我的IQueryable数据源执行LINQ操作。
搜索文本字段时,它使用.Contains(string)方法,该方法无法转换为SQL查询,并且会在本地进行评估。
是否可以强制EF Core更改LINQ查询(或由我自己执行)以使用.EF.Functions.Like(列,字符串)代替,因为它可以转换为SQL?
finished
答案 0 :(得分:1)
您可以在执行之前修改ExpressionTree
并将"".Contains()
调用替换为EF.Functions.Like("", "")
:
public static class LinqExtensions
{
public static IQueryable<T> FixQuery<T>(this IQueryable<T> query)
{
return query.Provider.CreateQuery<T>(
new FixQueryVisitor().Visit(query.Expression)
);
}
class FixQueryVisitor : ExpressionVisitor
{
private readonly MethodInfo _likeMethod = ExtractMethod(() => EF.Functions.Like(string.Empty, string.Empty));
private static MethodInfo ExtractMethod(Expression<Action> expr)
{
MethodCallExpression body = (MethodCallExpression)expr.Body;
return body.Method;
}
protected override Expression VisitMethodCall(MethodCallExpression node)
{
if (node.Method.DeclaringType == typeof(string) && node.Method.Name == "Contains")
{
return Expression.Call(this._likeMethod, Expression.Constant(EF.Functions), node.Object, node.Arguments[0]);
}
return base.VisitMethodCall(node);
}
}
}
[...]
dataSource = dataSource.FixQuery();