Почему: LINQ to Entities не распознает метод? - PullRequest
1 голос
/ 16 апреля 2020

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

В моем веб-приложении есть строка ниже, которая приводит к этому исключению:

LINQ to Entities не распознает метод 'System .Object FilterDeliveryAddressFields (WebApplication1.Models.DeliveryAddress) '

dynamic deliveryAddresses = (from address in db.DeliveryAddress
                             select filterDeliveryAddressFields(address)).ToList();

А вот filterDeliveryAddressFields:

private dynamic filterDeliveryAddressFields(DeliveryAddress address)
{
    return new { address.address, address.deliverTo, address.deliverToPhoneNumber, address.id };
}

А вот сгенерированный Linq-2- Sql Модель для DeliveryAddress, которая имеет отношение внешнего ключа с Subscriber:

public partial class DeliveryAddress
{
    public int id { get; set; }
    public int fkSubscriberId { get; set; }
    public string address { get; set; }
    public string deliverTo { get; set; }
    public string deliverToPhoneNumber { get; set; }

    public virtual Subscriber Subscriber { get; set; }
}

Но когда я изменяю элементы db.DeliveryAddress на первый список, а затем снова запускаю код, как показано ниже, все идет хорошо, и никаких исключений не возникает снова , Я хочу знать, что не так с первым фрагментом кода, которого нет в приведенном ниже фрагменте?

List<DeliveryAddress> addresseList = db.DeliveryAddress.ToList(); //magic trick?!
dynamic deliveryAddresses =
    (from address in addresseList
     select filterDeliveryAddressFields(address)).ToList();

Ответы [ 2 ]

1 голос
/ 16 апреля 2020

Согласен с @Salah. В LINQ to Entities сначала попытайтесь преобразовать ваш запрос в дерево команд и выполнить его в ORM. Пожалуйста, прочитайте здесь , вы можете найти более подробную информацию.

При первом подходе Linq пытается преобразовать ваш метод filterDeliveryAddressFields(address)) в дерево команд. Вот почему он жалуется, что LINQ to Entities does not recognize the method.

Во втором подходе вы выполняете со списком или IEnumerable<T>, что означает, что вы используете LINQ to Object. Подробнее об этом можно прочитать здесь .

В качестве первого решения вы можете попробовать другую реализацию. Просто попробуйте использовать агрегатный метод для фильтрации вашего результата. Тогда вам не нужен метод filterDeliveryAddressFields(address)). Вы можете найти пример здесь

Примерно так (Извините, я не пробовал это сам. Это только для вас, чтобы получить представление.)

from address in db.DeliveryAddress
select new { address.address, address.deliverTo, address.deliverToPhoneNumber, address.id };
1 голос
/ 16 апреля 2020

На самом деле, ваш метод не может быть переведен в T- SQL, Linq to Entities не может распознать каждый метод, волхвы c за методом .ToList(), который вы ищете, это после того, как данные при загрузке любая дальнейшая операция (например, select) выполняется с использованием LINQ to Objects для данных, уже находящихся в памяти.

Однако при этом подходе производительность не гарантируется, так как вы должны загрузить свои данные в память, так что представьте, у вас есть много данных в вашей БД, что будет дальше?

...