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;
}

Сообщите мне, если вам нужна дополнительная информация.

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

Аннели

Ответ 1

Как вы поняли, Entity Framework не может фактически запустить ваш код С# как часть его запроса. Он должен иметь возможность преобразовать запрос в фактический оператор 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()));
}

Ответ 2

Я получил ту же ошибку в этом коде:

 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

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

Ответ 3

У меня была проблема, похожая на вашу, и эта документация LINQ помогла мне найти правильные строковые функции, чтобы обойти ограничения.