Выражение LINQ не может быть переведено и будет оценено - PullRequest
1 голос
/ 03 мая 2019

Мой код:

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», где((SQLmatch ([sd] .Path1, __path1_0) AndAlso SQLmatch ([sd] .Path2, __path2_1)) AndAlso SQLmatch ([sd] .Path3, __path3_2)) 'не может быть переведено и будет оцениваться локально.'.Это исключение можно подавить или зарегистрировать, передав идентификатор события «RelationalEventId.QueryClientEvaluationWarning» методу «ConfigureWarnings» в «DbContext.OnConfiguring» или «AddDbContext».

Буду признателен за любую помощь в этом.

EDIT

Кажется, проблема в вызове функции, если я помещаю код в 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 Ответ

2 голосов
/ 03 мая 2019

В этом случае запрос будет преобразован в SQL и запущен на сервере базы данных, и вы можете использовать только те методы в запросах такого рода, которые поддерживаются LINQ и могут быть непосредственно преобразованы в функции БД.Таким образом, вы не можете использовать ваши пользовательские функции в этих запросах, даже если не все встроенные методы .net поддерживаются для LINQ для сущностей.Вы можете обратиться к этой ссылке для поддерживаемых функций.https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/supported-and-unsupported-linq-methods-linq-to-entities

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...