【问题标题】:The LINQ expression could not be translated and will be evaluated无法翻译 LINQ 表达式,将对其进行评估
【发布时间】:2019-05-03 00:46:35
【问题描述】:

我的代码:

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) AndAlso 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 不能在单独的函数中处理代码?

【问题讨论】:

  • 谢谢!你能解释一下为什么在没有函数调用的情况下嵌入代码时它会起作用吗?

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


【解决方案1】:

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

【讨论】:

  • 请查看我的编辑 - 如果我没有在单独的函数中使用相同的代码
  • 是的,这就是我试图解释的代码只有直接在查询中才能工作。它不适用于单独的函数,因为 LINQ 无法将您的自定义函数转换为 SQL。
猜你喜欢
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 2022-12-03
  • 1970-01-01
  • 2021-11-27
  • 2022-10-20
  • 2017-12-27
相关资源
最近更新 更多