无法翻译 LINQ 表达式并将对其求值

The LINQ expression could not be translated and will be evaluated

我的代码:

public static IQueryable<ServicesData> Query(DbContext dbc, string path1 = null, string path2 = null, string path3 = null) =>
    dbc.ServicesData.Where(sd => SQLmatch(sd.Path1, path1) && SQLmatch(sd.Path2, path2) && SQLmatch(sd.Path3, path3));

static bool SQLmatch(string match, string pattern) {
    if (match is null) match = "";
    if (pattern is null) pattern = "";
    bool wildcard = pattern.Contains("%") || pattern.Contains("_");
    return wildcard ? EF.Functions.Like(match, pattern) : object.Equals(match, pattern);
}

using (var dbc = new DbContext()) {
    var q = Query(dbc, "User", "%").ToList();

使用最新的 EFcore 3.0 失败:

Error generated for warning 'Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning: The LINQ expression 'where ((SQLmatch([sd].Path1, __path1_0) AndAlso SQLmatch([sd].Path2, __path2_1)) AndAlso SQLmatch([sd].Path3, __path3_2))' could not be translated and will be evaluated locally.'. This exception can be suppressed or logged by passing event ID 'RelationalEventId.QueryClientEvaluationWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.

如有任何帮助,我将不胜感激。

编辑

看来问题出在函数调用上,如果我将 SQLmatch 中的代码放入这样的单个表达式中:

public static IQueryable<ServicesData> Query(DbContext dbc, string path1 = null, string path2 = null, string path3 = null) =>
    dbc.ServicesData.Where(sd => 
    ((path1 ?? "").Contains("%") || (path1 ?? "").Contains("_") ? EF.Functions.Like((sd.Path1 ?? ""), (path1 ?? "")) : object.Equals((sd.Path1 ?? ""), (path1 ?? "")))
    && ((path2 ?? "").Contains("%") || (path2 ?? "").Contains("_") ? EF.Functions.Like((sd.Path2 ?? ""), (path2 ?? "")) : object.Equals((sd.Path2 ?? ""), (path2 ?? "")))
    && ((path3 ?? "").Contains("%") || (path3 ?? "").Contains("_") ? EF.Functions.Like((sd.Path3 ?? ""), (path3 ?? "")) : object.Equals((sd.Path3 ?? ""), (path3 ?? ""))));

有效!

为什么 EFCore 不能在单独的函数中处理代码?

在这种情况下,查询将在数据库服务器中转换为SQL和运行,您只能在LINQ支持的此类查询中使用那些方法,并且可以直接转换为数据库函数。因此,您不能在这些查询中使用您的自定义函数,甚至并非所有内置的 .net 方法都支持 LINQ to entities。支持的功能可以参考this linkhttps://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/supported-and-unsupported-linq-methods-linq-to-entities