3

我有以下课程,例如

public class Team
{
    [Key]
    public virtual Int32 TeamId { get; set; }
    [Required]
    public virtual String Name { get; set; }
    public virtual String Description { get; set; }
    public virtual ICollection<TeamFeed> TeamFeeds { get; set; }
}

public class TeamFeed
{       
    public Int32 TeamFeedId { get; set; }
    [Required]
    public Int32 TeamId { get; set; }
    public virtual bool IsEnabled { get; set; }
    public virtual Team Team { get; set; }
}

我有LazyLoadingEnabled = falseProxyCreationEnabled = false

当我做

var team = db.Teams.Where(x => x.TeamId == 1).Include(x=>x.TeamFeeds);

EF 生成的 SQL 如下所示:

SELECT 
[Project1].[TeamId] AS [TeamId], 
[Project1].[Name] AS [Name], 
[Project1].[Description] AS [Description], 
[Project1].[C1] AS [C1], 
[Project1].[TeamFeedId] AS [TeamFeedId], 
[Project1].[TeamId1] AS [TeamId1], 
[Project1].[IsEnabled] AS [IsEnabled], 
FROM ( SELECT 
    [Extent1].[TeamId] AS [TeamId], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Description] AS [Description],  
    [Extent2].[TeamFeedId] AS [TeamFeedId], 
    [Extent2].[TeamId] AS [TeamId1], 
    [Extent2].[IsEnabled] AS [IsEnabled],  
    CASE WHEN ([Extent2].[TeamFeedId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
    FROM  [dbo].[Teams] AS [Extent1]
    LEFT OUTER JOIN [dbo].[TeamFeeds] AS [Extent2] ON [Extent1].[TeamId] = [Extent2].[TeamId]
    WHERE 1 = [Extent1].[TeamId]
)  AS [Project1]
ORDER BY [Project1].[TeamId] ASC, [Project1].[C1] ASC

我不明白为什么它没有使用我会使用的 SQL 并创建了一个冗长的 SQL 语句。

SELECT 
* --use all just for clarity in the example
FROM TEAMS T

INNER JOIN TEAMFEEDS TF
ON T.TEAMID = TF.TEAMID

ORDER BY 
T.TEAMID

我是 EF 的新手,所以我可能不理解某些东西。

谢谢

4

1 回答 1

0

首先,当 Team with没有提要时,您的查询使用INNER JOIN不会返回任何内容。必须在这里使用,这就是 EF 在ineer 中所做的:TeamID = 1LEFT JOINSELECT

SELECT 
    *
    FROM  [dbo].[Teams] AS [Extent1]
    LEFT OUTER JOIN [dbo].[TeamFeeds] AS [Extent2] ON [Extent1].[TeamId] = [Extent2].[TeamId]
    WHERE 1 = [Extent1].[TeamId]

遵循可怕的路线只是让 EF 知道,如果指定了左侧站点-如果团队没有提要并且至少找到一个提要,JOIN它将返回。01

CASE WHEN ([Extent2].[TeamFeedId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]

而外部SELECT语句只是将数据库列名称映射到 EF 模型属性名称并执行ORDER BY

希望这足以解释为什么 EF 生成了如此冗长的 SQL 语句。或者更确切地说,为什么这句话看起来很吓人,但实际上并不比你的简单SELECT * FROM Teams JOIN Feeds

于 2013-04-04T11:40:48.907 回答