Entity Framework - свойства навигации, генерирующие дополнительные соединения

Я заметил очень уродливый SQL, сгенерированный моими запросами Entity Framework. Даже очень простые запросы генерируют много дополнительных JOIN, когда я проверяю SQL. OrderDate DATETIME

OrderHeaders

OrderID INT PK / FK
StatusID INT FK

StatusTypes

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 #.

Кто-нибудь знает, как это исправить?

5
задан Dismissile 21 February 2011 в 21:51
поделиться