Linq to Entities избыточные соединения в сгенерированном SQL

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

from c in Customer.GetCustomer(this.ClientId, intRecordId)
select new
{
  c.TitleId,
  c.FirstName,
  c.LastName,
  c.Phone,
  c.MobilePhone,
  c.Fax,
  c.EmailAddress,
  c.CustomerUserField.Text1,
  c.CustomerUserField.Text2,
  c.CustomerUserField.Text3,
  c.CustomerUserField.Text4,
  c.CustomerUserField.Text5
};

Это выглядит красиво и аккуратно в C #, однако сгенерированный SQL создает отдельное левое внешнее соединение для каждого столбца в указанной таблице:

SELECT 
[Limit1].[C1] AS [C1], 
[Limit1].[TitleId] AS [TitleId], 
...
FROM                                 
    [dbo].[Customer] AS [Extent1]
    LEFT OUTER JOIN [dbo].[CustomerUserField] AS [Extent2] ON [Extent1].[CustomerId] = [Extent2].[CustomerId]
    LEFT OUTER JOIN [dbo].[CustomerUserField] AS [Extent9] ON [Extent2].[CustomerUserFieldId] = [Extent9].[CustomerUserFieldId]
    LEFT OUTER JOIN [dbo].[CustomerUserField] AS [Extent10] ON [Extent2].[CustomerUserFieldId] = [Extent10].[CustomerUserFieldId]
    LEFT OUTER JOIN [dbo].[CustomerUserField] AS [Extent11] ON [Extent2].[CustomerUserFieldId] = [Extent11].[CustomerUserFieldId]
    LEFT OUTER JOIN [dbo].[CustomerUserField] AS [Extent12] ON [Extent2].[CustomerUserFieldId] = [Extent12].[CustomerUserFieldId]
    LEFT OUTER JOIN [dbo].[CustomerUserField] AS [Extent13] ON [Extent2].[CustomerUserFieldId] = [Extent13].[CustomerUserFieldId]...

Этот SQL очень медленный, так как требуется только одно левое внешнее соединение. Есть идеи, как я могу изменить свой LINQ для выполнения только одного соединения?

Заранее спасибо!

Энтони.


person antscode    schedule 20.04.2009    source источник
comment
Я бы проверил план выполнения, прежде чем сказать, что это плохо. Компиляция плана может понять и запросить CustomerUserField только один раз. Не уверен на 100%, но я видел, что такие запросы действительно неплохо оптимизируются.   -  person John Farrell    schedule 20.04.2009
comment
Плохо, по крайней мере, на SQL Server 2008 R2 и ранее. SQL Server не будет оптимизировать эти лишние соединения.   -  person Peter Radocchia    schedule 09.08.2011


Ответы (1)


вы можете «нетерпеливо загрузить» свою таблицу опций клиента, используя следующий код:

DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Customer>(c => c.CustomerUserField);

using (ToDoDataContext context = new ToDoDataContext())
{
    context.LoadOptions = options;
    //Your code goes here
}

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

person Matthew Steeples    schedule 20.04.2009
comment
LoadWith предназначен для LINQ to SQL. Используйте ObjectQuery.Include для LINQ to Entities. - person Craig Stuntz; 20.04.2009