C# 无法将编译查询中的EF.Functions.Like转换为SQL等效项

C# 无法将编译查询中的EF.Functions.Like转换为SQL等效项,c#,linq,entity-framework-core,C#,Linq,Entity Framework Core,我正在编写一个编译后的查询,它以DBContext和搜索字符串作为输入,并返回一个Class1列表 它基本上对class1对象运行3个过滤器,并返回class1对象的过滤列表。 private static Func<DbContext, string, IEnumerable<Class2>> Search = EF.CompileQuery((DbContextcontext, string query) => c

我正在编写一个编译后的查询,它以DBContext和搜索字符串作为输入,并返回一个Class1列表 它基本上对class1对象运行3个过滤器,并返回class1对象的过滤列表。

private static Func<DbContext, string, IEnumerable<Class2>> Search =
            EF.CompileQuery((DbContextcontext, string query) =>
            context.Class1
            .Where(c => c.param1.ToLower().Contains(query) && c.param2== 1 && c.param3!= 1)
            .OrderBy(p => p.param1.ToLower().StartsWith(query) ? 0 : 1)
            .Select(a => new Class2{ T1 = a.A1, T2 = a.A2, T3 = a.A3 })
            .Take(10).AsNoTracking());
主要查询:

var temp = await context.Class1.Where(c => EF.Functions.Like(c.param1, $"%{query}%") && c.param2== 1 && c.param3!= 1).OrderBy(p => EF.Functions.Like(p.param1, $"{query}%") ? 0 : 1).AsNoTracking().ToListAsync();
这实际上会过滤列表,然后按照以搜索查询开头的名称显示在其他名称之前的顺序对它们进行排序。 然后

到目前为止,这是我编写的编译查询:

private static Func<DbContext, string, IEnumerable<Class1>> Search =
            EF.CompileQuery((DbContext context, string query) =>
            context.Class1
            .Where(c => EF.Functions.Like(c.param1, $"%{query}%") 
             && c.param2== 1 
             && c.param3!= 1)
            );
private静态函数搜索=
EF.CompileQuery((DbContext上下文,字符串查询)=>
上下文1
.Where(c=>EF.Functions.Like(c.param1,$“%{query}%”)
&&c.param2==1
&&c.3!=1)
);
但是,当调用此编译查询时,它会引发此异常:无法翻译linq表达式

如何解决这个问题

更新:此问题现已解决。

private static Func<DbContext, string, IEnumerable<Class2>> Search =
            EF.CompileQuery((DbContextcontext, string query) =>
            context.Class1
            .Where(c => c.param1.ToLower().Contains(query) && c.param2== 1 && c.param3!= 1)
            .OrderBy(p => p.param1.ToLower().StartsWith(query) ? 0 : 1)
            .Select(a => new Class2{ T1 = a.A1, T2 = a.A2, T3 = a.A3 })
            .Take(10).AsNoTracking());
private静态函数搜索=
EF.CompileQuery((DbContextcontext,字符串查询)=>
上下文1
其中(c=>c.param1.ToLower().Contains(query)&&c.param2==1&&c.param3!=1)
.OrderBy(p=>p.param1.ToLower().StartsWith(查询)?0:1
.Select(a=>newclass2{T1=a.A1,T2=a.A2,T3=a.A3})
采取(10)行动;

如果您使用的是
EF-Core
,您不需要使用
CompileQuery
,只需使用
EF.Function.Like
,如下所示

    var users = context.Users.Where(a => EF.Functions.Like(a.FirstName, "%a%")).ToList();
因此,以这种方式重写代码如下:

    var result= context.Class1
        .Where(c => EF.Functions.Like(c.param1, $"%{query}%")
         && c.param2 == 1
         && c.param3 != 1).ToList();
  var users = context.Users.Where(a => EF.Functions.Like(a.FirstName, "%a%")).ToQueryString();
已更新:如果希望以t-sql的形式获取其结果,可以使用
ToQueryString()
如下所示:

    var result= context.Class1
        .Where(c => EF.Functions.Like(c.param1, $"%{query}%")
         && c.param2 == 1
         && c.param3 != 1).ToList();
  var users = context.Users.Where(a => EF.Functions.Like(a.FirstName, "%a%")).ToQueryString();
private静态函数搜索=
EF.CompileQuery((DbContextcontext,字符串查询)=>
上下文1
其中(c=>c.param1.ToLower().Contains(query)&&c.param2==1&&c.param3!=1)
.OrderBy(p=>p.param1.ToLower().StartsWith(查询)?0:1
.Select(a=>newclass2{T1=a.A1,T2=a.A2,T3=a.A3})
采取(10)行动;

您似乎遇到了另一个EF核心限制。问题不在于
EF.Functions.Like
方法,而在于内部插值字符串的使用,正如您所发现的,它在常规查询中有效,但在编译查询定义中无效

解决方案/解决方法是使用字符串串联代替字符串插值:

private static Func<DbContext, string, IEnumerable<Class1>> Search =
    EF.CompileQuery((DbContext context, string query) => context.Class1
    .Where(c => EF.Functions.Like(c.param1, "%" + query + "%") // <-- 
     && c.param2== 1 
     && c.param3!= 1)
    );

private静态函数搜索=
EF.CompileQuery((DbContext上下文,字符串查询)=>context.Class1

.Where(c=>EF.Functions.Like(c.param1,“%”+query+“%”//您使用的是什么版本的EF?您可以使用c.param1.Contains(query)吗?我使用的是EF-core。我可以使用c.param1.Contains(query),但它是区分大小写的,并且不确定在运行时是否更快请参见:如果使用Contains,可以使用StringComparison参数吗?在这里可以定义区分大小写。查看完整的异常消息。它会告诉您出了什么问题,这将提示如何修复它。获取后您将执行哪些操作g是否已编译?@SayanSen刚刚更新了我的答案。哦,你是说是的,因为编译后的查询已经事先编译成sql,为什么我需要EF.Functions。想将其转换成sql。对吗?我明白你的意思。谢谢。我已经更新了问题。@osmanRahimi问题是关于编译后的查询,而不是关于是否使用em也不知道其他选项。另外,
%a%
对范围变量
a
没有任何作用。好的。所以EF core编译查询不允许使用带$“{string}”的插值字符串,但允许字符串concat?这对我来说是一个很大的学习。谢谢!