繁体   English   中英

实体框架6联接过多

[英]Entity Framework 6 too many joins

我有以下LINQ查询:

var query = from a in c.ArticleSet
            where a.GlobalAccess == false && 
                  a.Published == true && 
                  a.MagazineSet.IsPublished == true && 
                  a.MagazineSet.Press_Id == pressId && 
                  a.Tests.Id==a.Id && 
                  a.Tests.IsDeleted == false && 
                  a.Tests.IsPublished == true
            orderby a.Id descending
            select a.Id;

像这样转换为SQL:

ADO.NET:Execute Reader "SELECT 
[Project1].[Id] AS [Id]
FROM ( SELECT 
    [Filter3].[Id1] AS [Id]
    FROM   (SELECT [Filter2].[Id1], [Filter2].[Magazine_Id1], [Filter2].[Press_Id1], [Filter2].[Press_Id2], [Filter2].[Press_Id3]
        FROM    (SELECT [Filter1].[Id1], [Filter1].[Magazine_Id1], [Extent5].[Press_Id] AS [Press_Id1], [Extent6].[Press_Id] AS [Press_Id2], [Extent7].[Press_Id] AS [Press_Id3]
            FROM       (SELECT [Extent1].[Id] AS [Id1], [Extent1].[Magazine_Id] AS [Magazine_Id1]
                FROM   [dbo].[ArticleSet] AS [Extent1]
                INNER JOIN [dbo].[Tests] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[Id]) AND ([Extent2].[Id] = [Extent1].[Id])
                INNER JOIN [dbo].[MagazineSet] AS [Extent3] ON [Extent1].[Magazine_Id] = [Extent3].[Id]
                WHERE (0 = [Extent1].[GlobalAccess]) AND (1 = [Extent1].[Published]) AND (1 = [Extent3].[IsPublished]) ) AS [Filter1]
            INNER JOIN [dbo].[MagazineSet] AS [Extent4] ON [Filter1].[Magazine_Id1] = [Extent4].[Id]
            LEFT OUTER JOIN [dbo].[MagazineSet] AS [Extent5] ON [Filter1].[Magazine_Id1] = [Extent5].[Id]
            LEFT OUTER JOIN [dbo].[MagazineSet] AS [Extent6] ON [Filter1].[Magazine_Id1] = [Extent6].[Id]
            LEFT OUTER JOIN [dbo].[MagazineSet] AS [Extent7] ON [Filter1].[Magazine_Id1] = [Extent7].[Id]
            INNER JOIN [dbo].[Tests] AS [Extent8] ON [Filter1].[Id1] = [Extent8].[Id]
            WHERE 0 = [Extent8].[IsDeleted] ) AS [Filter2]
        INNER JOIN [dbo].[Tests] AS [Extent9] ON [Filter2].[Id1] = [Extent9].[Id]
        INNER JOIN [dbo].[Tests] AS [Extent10] ON [Filter2].[Id1] = [Extent10].[Id]
        WHERE 1 = [Extent10].[IsPublished] ) AS [Filter3]
    INNER JOIN [dbo].[Tests] AS [Extent11] ON [Filter3].[Id1] = [Extent11].[Id]
    WHERE (([Filter3].[Press_Id1] = @p__linq__0) AND ( NOT ([Filter3].[Press_Id2] IS NULL OR @p__linq__0 IS NULL))) OR (([Filter3].[Press_Id3] IS NULL) AND (@p__linq__0 IS NULL))
)  AS [Project1]
ORDER BY [Project1].[Id] DESC"

命令文字

"SELECT [Project1].[Id] AS [Id]
FROM ( SELECT 
    [Filter3].[Id1] AS [Id]
    FROM   (SELECT [Filter2].[Id1], [Filter2].[Magazine_Id1], [Filter2].[Press_Id1], [Filter2].[Press_Id2], [Filter2].[Press_Id3]
        FROM    (SELECT [Filter1].[Id1], [Filter1].[Magazine_Id1], [Extent5].[Press_Id] AS [Press_Id1], [Extent6].[Press_Id] AS [Press_Id2], [Extent7].[Press_Id] AS [Press_Id3]
            FROM       (SELECT [Extent1].[Id] AS [Id1], [Extent1].[Magazine_Id] AS [Magazine_Id1]
                FROM   [dbo].[ArticleSet] AS [Extent1]
                INNER JOIN [dbo].[Tests] AS [Extent2] ON ([Extent1].[Id] = [Extent2].[Id]) AND ([Extent2].[Id] = [Extent1].[Id])
                INNER JOIN [dbo].[MagazineSet] AS [Extent3] ON [Extent1].[Magazine_Id] = [Extent3].[Id]
                WHERE (0 = [Extent1].[GlobalAccess]) AND (1 = [Extent1].[Published]) AND (1 = [Extent3].[IsPublished]) ) AS [Filter1]
            INNER JOIN [dbo].[MagazineSet] AS [Extent4] ON [Filter1].[Magazine_Id1] = [Extent4].[Id]
            LEFT OUTER JOIN [dbo].[MagazineSet] AS [Extent5] ON [Filter1].[Magazine_Id1] = [Extent5].[Id]
            LEFT OUTER JOIN [dbo].[MagazineSet] AS [Extent6] ON [Filter1].[Magazine_Id1] = [Extent6].[Id]
            LEFT OUTER JOIN [dbo].[MagazineSet] AS [Extent7] ON [Filter1].[Magazine_Id1] = [Extent7].[Id]
            INNER JOIN [dbo].[Tests] AS [Extent8] ON [Filter1].[Id1] = [Extent8].[Id]
            WHERE 0 = [Extent8].[IsDeleted] ) AS [Filter2]
        INNER JOIN [dbo].[Tests] AS [Extent9] ON [Filter2].[Id1] = [Extent9].[Id]
        INNER JOIN [dbo].[Tests] AS [Extent10] ON [Filter2].[Id1] = [Extent10].[Id]
        WHERE 1 = [Extent10].[IsPublished] ) AS [Filter3]
    INNER JOIN [dbo].[Tests] AS [Extent11] ON [Filter3].[Id1] = [Extent11].[Id]
    WHERE (([Filter3].[Press_Id1] = @p__linq__0) AND ( NOT ([Filter3].[Press_Id2] IS NULL OR @p__linq__0 IS NULL))) OR (([Filter3].[Press_Id3] IS NULL) AND (@p__linq__0 IS NULL))
)  AS [Project1]
ORDER BY [Project1].[Id] DESC

我认为在此示例中3 join就足够了。 为什么实体框架会创建如此庞大的查询?

您的linq查询很好,除了它一次引用很多表。 如果这确实是您想要的,那就没有什么可害怕的了。 这不是唯一的“超级高效”,因为您一次引用了3个表。

只需记住EF生成的sql查询是机器创建的。 它并不总是最好的,但始终应该是完全有效的。 我不确定为什么要选择这种形式而不是另一种形式,但是如果可行,为什么要担心呢?

我总是建议人们将查询限制为仅需要的引用表。 随着系统的发展,处理时间也将增加,并且由于有如此多的表联接,它可能开始变得更加引人注目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM