LINQ to Entities не распознает метод

Я получаю следующую ошибку при попытке выполнить запрос linq:

LINQ to Entities не распознает метод Boolean IsCharityMatching (System.String, System.String), и этот метод нельзя преобразовать в выражение хранилища.

Я читал много предыдущих вопросов, где люди получают ту же ошибку, и если я правильно это понимаю, это потому, что LINQ to Entities требует, чтобы все выражение запроса linq было преобразовано в запрос сервера, и поэтому вы не можете вызвать внешний метод в этом. Мне еще не удалось превратить свой сценарий во что-то, что работает, и мой мозг начинает таять, поэтому я надеялся, что кто-то может указать мне правильное направление. Мы используем Entity Framework и шаблон спецификации (и я новичок в обоих).

Вот код, в котором используется спецификация:

ISpecification<Charity> specification = new CharitySearchSpecification(charityTitle, charityReference);

charities = charitiesRepository.Find(specification).OrderBy(p => p.RegisteredName).ToList();

Вот выражение linq:

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    return p => p.IsCharityMatching(this.charityName, this.charityReference);
}

Вот метод IsCharityMatching:

public bool IsCharityMatching(string name, string referenceNumber)
{
    bool exists = true;

    if (!String.IsNullOrEmpty(name))
    {
        if (!this.registeredName.ToLower().Contains(name.ToLower()) &&
            !this.alias.ToLower().Contains(name.ToLower()) &&
           !this.charityId.ToLower().Contains(name.ToLower()))
        {
            exists = false;
        }
    }

    if (!String.IsNullOrEmpty(referenceNumber))
    {
        if (!this.charityReference.ToLower().Contains(referenceNumber.ToLower()))
        {
            exists = false;
        }
    }

    return exists;
}

Дайте мне знать, если вам понадобится дополнительная информация.

Большое спасибо,

Аннели


person annelie    schedule 31.08.2011    source источник
comment
проверьте этот ответ   -  person Eranga    schedule 31.08.2011
comment
Проверим и это, спасибо!   -  person annelie    schedule 31.08.2011
comment
Было бы неплохо увидеть, как вы используете Find(), когда вы используете IsSatisfied() внутри него.   -  person Alisson    schedule 19.03.2017


Ответы (5)


Как вы уже поняли, Entity Framework не может выполнять ваш код C # как часть своего запроса. Он должен иметь возможность преобразовывать запрос в фактический оператор SQL. Чтобы это сработало, вам нужно будет преобразовать выражение запроса в выражение, которое может обрабатывать Entity Framework.

public System.Linq.Expressions.Expression<Func<Charity, bool>> IsSatisfied()
{
    string name = this.charityName;
    string referenceNumber = this.referenceNumber;
    return p => 
        (string.IsNullOrEmpty(name) || 
            p.registeredName.ToLower().Contains(name.ToLower()) ||
            p.alias.ToLower().Contains(name.ToLower()) ||
            p.charityId.ToLower().Contains(name.ToLower())) &&
        (string.IsNullOrEmpty(referenceNumber) ||
            p.charityReference.ToLower().Contains(referenceNumber.ToLower()));
}
person StriplingWarrior    schedule 31.08.2011
comment
в случае сомнений найдите его: stackoverflow.com/questions/ 2352764 / - person Chris Hayes; 19.02.2015
comment
Возврат сконструированного Expression<Func<T,type>> - очень хороший подход к этому. - person Travis J; 26.08.2017
comment
Как бы вы использовали это в выражении LINQ? Я хотел бы сделать что-то подобное как предложение Where, которое можно использовать повторно, но мне сложно его реализовать. - person Zorgarath; 27.10.2017
comment
РЕДАКТИРОВАТЬ: неважно, это будет: context.Where(IsSatisfied()) - person Zorgarath; 27.10.2017
comment
Ключевая часть: Entity Framework не может фактически запускать ваш код C # как часть своего запроса. - person Alper; 31.12.2018

У меня такая же ошибка в этом коде:

 var articulos_en_almacen = xx.IV00102.Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

это была именно ошибка:

System.NotSupportedException: 'LINQ to Entities не распознает метод' Boolean Exists (System.Predicate`1 [conector_gp.Models.almacenes_por_sucursal]) ', и этот метод нельзя преобразовать в выражение хранилища.'

Я решил так:

var articulos_en_almacen = xx.IV00102.ToList().Where(iv => alm_x_suc.Exists(axs => axs.almacen == iv.LOCNCODE.Trim())).Select(iv => iv.ITEMNMBR.Trim()).ToList();

Я добавил .ToList () перед своей таблицей, это разделяет код Entity и linq и позволяет избежать перевода следующего выражения linq

ПРИМЕЧАНИЕ. это решение не оптимально, поскольку избегает фильтрации сущностей и просто загружает всю таблицу в память.

person Ing. Gerardo Sánchez    schedule 14.01.2019
comment
В большинстве случаев это самое простое решение, но чтобы не загружать весь объект, я обычно делаю анонимный выбор перед .ToList () с тем, что мне нужно ... xx.Select (x = ›new {x.Id, x.DateTimeUpdate }). ToList (). Select (x = ›new {x.Id, DateTimeUpdate = x.DateTimeUpdate.ToString (dd / MM / yyyy)}) - person Diógenes; 22.01.2019

Если кто-то ищет ответ VB.Net (как и я изначально), вот он:

Public Function IsSatisfied() As Expression(Of Func(Of Charity, String, String, Boolean))

Return Function(charity, name, referenceNumber) (String.IsNullOrWhiteSpace(name) Or
                                                         charity.registeredName.ToLower().Contains(name.ToLower()) Or
                                                         charity.alias.ToLower().Contains(name.ToLower()) Or
                                                         charity.charityId.ToLower().Contains(name.ToLower())) And
                                                    (String.IsNullOrEmpty(referenceNumber) Or
                                                     charity.charityReference.ToLower().Contains(referenceNumber.ToLower()))
End Function
person Mik    schedule 14.11.2019

Сегодня я столкнулся с той же проблемой, это была первая ссылка, на которую я попал. Однако я не искал проверки своего запроса. Поэтому, если у кого-то такая же проблема и он ищет это решение, оно будет добавлено сюда. Моя проблема заключалась в другой ссылке.

Это наиболее частое исключение, возникающее при работе со структурой сущностей и преобразовании данных в результат IQueryable для фильтрации.

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems
        .Where(i => i.Code == code.ToString())
        .FirstOrDefault();
}

Существует несколько решений. Переместите вызов ToString () в отдельную строку.

using (var context = new CustomerContext())
{
    string codeStr = code.ToString();
    var item = context.InvoiceItems
        .Where(i => i.Code == codeStr)
        .FirstOrDefault();
}

Используйте метод расширения EF,

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems
        .Where(i => i.Code == SqlFunctions.StringConvert(code))
        .FirstOrDefault();
}

Преобразование результата IQueryable в IEnumerable перед фильтрацией

using (var context = new CustomerContext())
{
    var item = context.InvoiceItems.AsEnumerable()
        .Where(i => i.Code == code.ToString())
        .FirstOrDefault();
}
person JTIM    schedule 22.03.2021

У меня такая же ошибка в этом коде:

Решение

IQuerable to

.toList () - лучший вариант

person Sameer Bahad    schedule 31.05.2021