LINQ表达式无法翻译,将被评估

时间:2019-05-03 00:46:35

标签: c# .net-core entity-framework-core .net-core-3.0

我的代码:

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会失败,并显示以下信息:

  

生成警告错误   'Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning:   LINQ表达式'where((SQLmatch([sd] .Path1,__path1_0)And   SQLmatch([sd] .Path2,__path2_1))还有SQLmatch([sd] .Path3,   __path3_2))'无法翻译,将在本地进行评估。可以通过传递事件ID来抑制或记录此异常   'RelationalEventId.QueryClientEvaluationWarning'到   'DbContext.OnConfiguring'中的'ConfigureWarnings'方法或   “ 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无法在单独的函数中处理代码?

1 个答案:

答案 0 :(得分:2)

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