为什么Linq to Entities返回的连接多于必要的连接数

时间:2014-10-21 11:12:37

标签: c# linq-to-entities

我想问为什么Linq to Entities返回的连接数超过了必要的数量,以及改进它们的方法。

这是我的代码:

var items = dc.WHItems
        .Select(c => new testModel()
        {
          ID = c.ID,
          Name = c.Name,
          Code = c.Code,
          Discontinued = c.Discontinued,
          Type = c.WHItemType.Name,
          Category = c.WHItemType.WHItemCategory.Name
        })
        .Where(c => c.Discontinued == false)
        .Take(10);

从SQL事件探查器获取结果SQL

  SELECT TOP (10) 
  [Extent1].[ID] AS [ID], 
  [Extent1].[Name] AS [Name], 
  [Extent1].[Code] AS [Code], 
  [Extent1].[Discontinued] AS [Discontinued], 
  [Extent2].[Name] AS [Name1], 
  [Extent4].[Name] AS [Name2]
  FROM    [dbo].[WHItems] AS [Extent1]
  INNER JOIN [dbo].[WHItemTypes] AS [Extent2] ON [Extent1].[WHItemTypeID] = [Extent2].[ID]
  LEFT OUTER JOIN [dbo].[WHItemTypes] AS [Extent3] ON [Extent1].[WHItemTypeID] = [Extent3].[ID]
  LEFT OUTER JOIN [dbo].[WHItemCategories] AS [Extent4] ON [Extent3].[WHItemCategoryID] = [Extent4].[ID]
  WHERE 0 = [Extent1].[Discontinued]

然而使用LINQPad4,结果查询让我满意

SELECT TOP (10) [t0].[ID], [t0].[Name], [t0].[Code], [t0].[Discontinued], [t1].[Name] AS [Type], [t2].[Name] AS [Category]
FROM [WHItems] AS [t0]
INNER JOIN [WHItemTypes] AS [t1] ON [t1].[ID] = [t0].[WHItemTypeID]
INNER JOIN [WHItemCategories] AS [t2] ON [t2].[ID] = [t1].[WHItemCategoryID]
WHERE NOT ([t0].[Discontinued] = 1)

这是另一个代码,我尝试从库存中获取项目。表WHInventories在WHItemID和WHID上使用复合键,我认为这解释了如上所述使用'Inner Join'而不是'Left Join'的选择。

  var items = dc.WHInventories
    .Select(c => new testModel()
    {
      ID = c.WHItemID,
      Name = c.WHItem.Name,
      Code = c.WHItem.Code,
      Discontinued = c.WHItem.Discontinued
    })
    .Where(c => c.Discontinued == false)
    .Take(10);

SQL Profiler中的结果查询显示了额外的左外连接。为什么必须从Extent3中检索列代码?列名称和已停止使用相同的Extent2

  SELECT TOP (10) 
  [Extent1].[WHItemID] AS [WHItemID], 
  [Extent2].[Name] AS [Name], 
  [Extent3].[Code] AS [Code], 
  [Extent2].[Discontinued] AS [Discontinued]
  FROM   [dbo].[WHInventories] AS [Extent1]
  INNER JOIN [dbo].[WHItems] AS [Extent2] ON [Extent1].[WHItemID] = [Extent2].[ID]
  LEFT OUTER JOIN [dbo].[WHItems] AS [Extent3] ON [Extent1].[WHItemID] = [Extent3].[ID]
  WHERE 0 = [Extent2].[Discontinued]

如果我尝试显式连接,这意味着失去了拥有'导航属性'的优势。

  var items = dc.WHInventories
    .Join(dc.WHItems, c => c.WHItemID, d => d.ID, (c, d) => new { c, d })
    .Select(c => new testModel()
    {
      ID = c.c.WHItemID,
      Name = c.d.Name,
      Code = c.d.Code,
      Discontinued = c.d.Discontinued
    })
    .Where(c => c.Discontinued == false)
    .Take(10);

SQL Profiler中的结果查询显示了我的预期。列代码现在使用Extent2

  SELECT TOP (10) 
  [Extent1].[WHItemID] AS [WHItemID], 
  [Extent2].[Name] AS [Name], 
  [Extent2].[Code] AS [Code], 
  [Extent2].[Discontinued] AS [Discontinued]
  FROM  [dbo].[WHInventories] AS [Extent1]
  INNER JOIN [dbo].[WHItems] AS [Extent2] ON [Extent1].[WHItemID] = [Extent2].[ID]
  WHERE 0 = [Extent2].[Discontinued]

0 个答案:

没有答案