Я заметил очень уродливый SQL, сгенерированный моими запросами Entity Framework. Даже очень простые запросы генерируют много дополнительных JOIN, когда я проверяю SQL. OrderDate DATETIME
OrderID INT PK / FK
StatusID INT FK
StatusID INT PK
Описание NVARCHAR (50)
Исходя из модели, заказ может иметь 0 или 1 заголовок заказа. Заголовок будет иметь 1. Тип состояния.
Я создал следующий запрос:
var orders = from o in db.Orders
where o.OrderID == 1
select new
{
Order = o,
Status = o.OrderHeader.Status
};
Сгенерированный этим SQL-запрос выглядел так:
SELECT
[Extent1].[OrderID] AS [OrderID],
[Extent1].[OrderDate] AS [OrderDate],
[Extent4].[StatusID] AS [StatusID],
[Extent4].[Description] AS [Description]
FROM [dbo].[Orders] AS [Extent1]
LEFT OUTER JOIN [dbo].[OrderHeaders] AS [Extent2] ON [Extent1].[OrderID] = [Extent2].[OrderID]
LEFT OUTER JOIN [dbo].[OrderHeaders] AS [Extent3] ON [Extent2].[OrderID] = [Extent3].[OrderID]
LEFT OUTER JOIN [dbo].[StatusTypes] AS [Extent4] ON [Extent3].[OrderID] = [Extent4].[OrderID]
WHERE 1 = [Extent1].[OrderID]
Как вы можете видеть, в запросе есть два ненужных левых соединения. Почему SQL создается именно так? Я неправильно спрашиваю? Я не должен использовать свойства навигации в запросе?
Нужно ли мне прибегать к написанию объединений в самом запросе, чтобы он не создавал для меня дополнительных объединений? Когда я пишу запрос с использованием объединений, сгенерированный SQL не имеет дополнительных соединений, но запрос LINQ to Entities намного уродливее / более подробен:
var orders = from o in db.Orders
join h in db.OrderHeaders on o.OrderID equals h.OrderID into orderHeader
from h in orderHeader.DefaultIfEmpty()
join s in db.StatusTypes on h.StatusID equals s.StatusID into statusType
from s in statusType.DefaultIfEmpty()
where o.OrderID == 1
select new
{
o,
s
};
Он генерирует SQL без дополнительных объединений, но выглядит гораздо уродливее. at со стороны C #.
Кто-нибудь знает, как это исправить?