Не поддерживается в LINQ to Entities - PullRequest
0 голосов
/ 10 января 2019

Каждый раз, когда я использую расширение Include, оно будет возвращать ошибку, если значение из включенной сущности используется в WHERE CLAUSE .

Я включил System.Data.Entity , который является общим ответом, но все еще имеет ту же проблему.

Модель:

public partial class business_partner
{
public int id { get; set; }
public string accountid { get; set; }
}

public partial class order
{
public int id { get; set; }
public string doc_number { get; set; }
public int vendor_id { get; set; }
public int status { get; set; };

[ForeignKey("vendor_id")]
public virtual business_partner businessPartnerVendor { get; set; }
}

public IQueryable<order> GetOrder()
{
return (context.order);
}

Запрос:

_orderService.GetOrder()
.Include(a => a.businessPartnerVendor)  
.Where(o => o.doc_number == "Order Number"
&& o.businessPartnerVendor.accountid == "TEST"
&& o.status > 2 && o.status != 9).Count() > 0

Исключение:

Указанный член типа 'businessPartnerVendor' не поддерживается в LINQ to Entities. Поддерживаются только инициализаторы, элементы сущностей и свойства навигации сущностей.

1 Ответ

0 голосов
/ 10 января 2019

Увы, вы забыли написать свое требование. Ваш код не делает то, что вы хотите, поэтому я могу прийти к неправильному выводу, но, глядя на ваш код, кажется, что вы хотите следующее:

Скажите, есть ли Orders, что
- иметь значение DocNumber, равное "Order_Number",
- И это порядки BusinessPartnerVendor со значением AccountId, равным «ТЕСТ»,
- И имеют значение Status, которое больше 2 и не равно 9.

Часть "Скажи мне, есть ли Orders это", была вычтена из-за того, что ты только хочешь знать, является ли Count() > 0

Ваш счетчик соединил бы все элементы, включил все столбцы BusinessPartnerVendor, удалил все строки, не соответствующие вашему местоположению, и подсчитал, сколько осталось соединенных элементов. Это целочисленное значение будет передано, после чего ваш процесс проверит, является ли значение больше нуля.

Одной из более медленных частей запроса к базе данных является передача выбранных данных из системы управления базами данных в локальный процесс. Следовательно, разумно ограничить количество передаваемых данных.

Довольно часто я вижу людей, использующих Include, чтобы получить предметы, которые хранятся в другой таблице (довольно часто «один ко многим»). Это выберет полный ряд. От businessPartnerVendor вы хотите использовать только свойство AccountId. Так зачем выбирать законченный объект?

В платформе сущностей используйте Select для выбора свойств, которые вы хотите запросить. Используйте Включить, только если вы хотите обновить извлеченные данные.

bool areTestOrdersAvailable = orderService.GetOrder()
   .Where(order => order.doc_number == "Order Number"
       && order.businessPartnerVendor.accountid == "TEST"
       && order.status > 2 && order.status != 9)
   .Any();

Из-за виртуального ключевого слова в ваших классах (и, может быть, некоторого свободного API), структура сущностей знает об отношении «один ко многим» и выполнит правильное соединение для вас. Он будет использовать SQL «TAKE 1» только для определения наличия каких-либо элементов. Передается только один логический

Несколько советов о структуре сущностей

Хорошей практикой является как можно больше придерживаться первых соглашений кода структуры сущностей Чем больше вы это делаете, тем меньше нужно атрибутов и свободно API. Также будет меньше расхождений между способом использования Microsoft идентификаторов для классов, полей, свойств, методов и т. Д. И вашим.

В структуре сущностей все столбцы таблицы представлены не виртуальными свойствами, виртуальные свойства представляют отношения между таблицами (один ко многим, многие ко многим, ...)

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

Поэтому решите, использовать ли business_partner или BusinessPartnerVendor, если они на самом деле такие же вещи

Добавить внешний ключ:

// Every Order is the Order of exactly one BusinessPartner, using foreign key (one-to-many)
public int BusinessPartnerId {get; set;}
public virtual BusinessPartner BusinessPartner {get; set;}

Это имеет то преимущество, что если вы хотите выбрать идентификаторы всех BusinessPartners, у которых есть один или несколько Orders, что ..., вам не нужно выполнять соединение:

var businessPartnerIds = myDbContext.Orders
    .Where(order => ...)
    .Select(order => order.BusinessPartnerId)
    .Distinct();

Будет доступна только одна таблица базы данных

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