Я столкнулся с проблемой, которая меня озадачила. Когда я пытаюсь объединить две таблицы вместе, запрос ко второй таблице генерирует внутреннее соединение назад к первой таблице. Весь смысл использования объединения - вернуть результат, если запись существует в любой таблице, но это внутреннее соединение приводит к сбою, если запись находится во второй таблице, но не первая.
Я сделал несколько тестов в гораздо меньших масштабах, чтобы увидеть, схожу ли я с ума, и это, похоже, не так.
У меня есть две таблицы: OrderDetails и OrderDetailHistories. Предыстория: после определенного периода времени записи удаляются из таблицы подробностей и помещаются в таблицу историй. Поля и все точно такие же. Фактически, это объект для OrderDetailHistories:
public partial class OrderDetailsHistory : OrderDetail { }
Итак, чтобы начать, я написал небольшой тестовый запрос, который довольно хорошо отражает то, что я вижу.
var test = this.context.OrderDetails
.Select(x => x.Descr)
.Union(this.context.OrderDetailsHistories
.Select(x => x.Descr))
.Where(x => x == "wat")
.ToList();
Что генерирует этот запрос:
SELECT
[Distinct1].[C1] AS [C1]
FROM ( SELECT DISTINCT
[UnionAll1].[Descr] AS [C1]
FROM (SELECT
[Extent1].[Descr] AS [Descr]
FROM [dbo].[OrderDetails] AS [Extent1]
WHERE N'wat' = [Extent1].[Descr]
UNION ALL
SELECT
[Extent3].[Descr] AS [Descr]
FROM [dbo].[OrderDetails_History] AS [Extent2]
INNER JOIN [dbo].[OrderDetails] AS [Extent3] ON ([Extent2].[Order_No] = [Extent3].[Order_No])
WHERE N'wat' = [Extent3].[Descr]) AS [UnionAll1]
) AS [Distinct1]
А? Почему этот второй оператор выбора даже ссылается на таблицу данных? Что происходит, когда я использую concat? То же самое. Перекрыть? Такое же внутреннее соединение. Хорошо, возможно, вместо того, чтобы сначала объединиться, а затем применив мое условие, я могу применить условия для каждого запроса, а затем просто объединить результаты.
Как насчет этого?
var query1 = this.context.OrderDetails.Where(x => x.Descr == "wat").Select(x => x.Descr);
var query2 = this.context.OrderDetailsHistories.Where(x => x.Descr == "wat").Select(x => x.Descr);
var result = query1.Concat(query2).ToList();
Создает почти тот же самый запрос! Кто-нибудь знает, что здесь происходит? Ожидаются ли мои ожидания?
Если я напишу.ToList() в конце вышеперечисленных запросов query1 и query2, он будет работать точно так, как я ожидал, но тогда я теряю способность делать подкачки в sql и в конечном итоге снимаю слишком много записей, когда мы 'только отображение 10 на страницу.
Любая помощь будет оценена по достоинству.
Я не знаю, какой подход вы используете EF, я предполагаю, что код сначала. Но в любом случае вы используете его неправильно или вы не знаете, как это работает. Когда вы наследуете свой класс OrderDetailsHistory
из OrderDetail
тогда он говорит, что OrderDetailsHistory
всегда является OrderDetail
.
Поэтому, если вы хотите выбрать все заказы, вы можете просто запросить OrderDetail
и будут также все объекты OrderDetailsHistory
:
this.context.OrderDetails
.Select(x => x.Descr)
.Where(x => x == "wat")
.ToList();
Также важно знать, как данные хранятся в вашей БД. Вы используете таблицу в классе aproach - читайте некоторые статьи об этом (например, http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table -per-type-tpt), чтобы понять, как это работает, тогда вы также поймете, почему все ваши запросы выглядят "такими странными"...