Accepted answer

You seems to be hitting yet another EF Core limitation. The problem is not the EF.Functions.Like method, but the usage of the interpolated string inside, which as you found works inside regular query, but not inside compiled query definition.

The solution/workaround is to use string concatenation in place of string interpolation:

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)

The resulting SQL query is a bit different, but at least you got a translation.


If you are using EF Core, you don't need using CompileQuery, just use Ef.Function.Like as below

    var users = context.Users.Where(a => EF.Functions.Like(a.FirstName, "%a%")).ToList();

So Rewriting your code in this way would be like this:

    var result= context.Class1
        .Where(c => EF.Functions.Like(c.param1, $"%{query}%")
         && c.param2 == 1
         && c.param3 != 1).ToList();

Updated: If you want to get its result as t-sql, you can use ToQueryString() like this:

  var users = context.Users.Where(a => EF.Functions.Like(a.FirstName, "%a%")).ToQueryString();


private static Func<DbContext, string, IEnumerable<Class2>> Search =
            EF.CompileQuery((DbContextcontext, string query) =>
            .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 })

Related Articles