简体   繁体   English

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

[英]The LINQ expression could not be translated and will be evaluated

My code: 我的代码:

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();

Using latest EFcore 3.0 this fails with: 使用最新的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.'. 警告'Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning生成的错误:LINQ表达式'其中((SQLmatch([sd] .Path1,__path1_0)AndAlso SQLmatch([sd] .Path2,__path2_1))AndAlso SQLmatch([sd] .Path3 ,__path3_2))'无法翻译,将在本地进行评估。'。 This exception can be suppressed or logged by passing event ID 'RelationalEventId.QueryClientEvaluationWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'. 可以通过将事件ID“ RelationalEventId.QueryClientEvaluationWarning”传递到“ DbContext.OnConfiguring”或“ AddDbContext”中的“ ConfigureWarnings”方法来抑制或记录此异常。

I would appreciate any help with this. 我将不胜感激。

EDIT 编辑

It seems the problem is with the function call, if I put the code in SQLmatch into a single expression like this: 似乎问题出在函数调用上,如果我将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 ?? ""))));

it works ! 有用 !

Why can't EFCore process the code in a separate function ? EFCore为什么不能在单独的函数中处理代码?

In this case, the query will be converted to SQL and run in the database server and you can only use those methods in these kinds of queries which are supported by LINQ and can be directly converted to DB functions. 在这种情况下,查询将转换为SQL并在数据库服务器中运行,并且您只能在LINQ支持的这些类型的查询中使用这些方法,并且可以将它们直接转换为DB函数。 So you cannot use your custom functions in these queries, even not all the inbuilt .net methods are supported for LINQ to entities. 因此,即使不是LINQ to实体也不支持所有内置.net方法,也不能在这些查询中使用自定义函数。 You can refer to this link for supported functions. 您可以参考此链接以获取受支持的功能。 https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/supported-and-unsupported-linq-methods-linq-to-entities https://docs.microsoft.com/zh-cn/dotnet/framework/data/adonet/ef/language-reference/supported-and-unsupported-linq-methods-linq-to-entities

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM