简体   繁体   中英

difficulty to translate a sql query into a linq to entity query

I have this schemas (i did simplify it so i can easily post it here)

图

and this sql query, the variable/entry point would be the in (1,2,3)

SELECT c1.ChildId1
         , c1.Info1
         , m1.Info
         , l1.Description1
         , l2.Description2
         , l2.Description3

from dbo.ChildTable1 c1

        inner join dbo.MasterTable m1
           on m1.MasterId = c1.MasterId

        inner join dbo.LookupTable1 l1
           on c1.LookupId1 = l1.LookupId1             

        inner join dbo.ChildTable2 c2             
           on m1.MasterId = c2.MasterId

        inner join dbo.LookupTable2 l2
           on c2.LookupId2 = l2.LookupId2

where c1.ChildId1 in (select max(c.ChildId1) 
                      from dbo.ChildTable1 c
                      where c.ExtraId in (1,2,3)
                      group by c.MasterId)

                AND

      c2.ChildId2 in (select max(c.ChildId2)                               
                      from dbo.ChildTable2 c
                      where c.MasterId = m1.MasterId
                      group by c.MasterId)

i managed to write this linq to entity query, it does return the same result so far

var value = (new int?[] { 1, 2, 3 });

var query = (from c1 in db.ChildTable1
                where db.ChildTable1.Where(x => value.Contains(x.ExtraId)).GroupBy(x => x.MasterId).Select(x => x.Max(y => y.ChildId1)).Contains(c1.ChildId1)
                select new
                {
                    c1.ChildId1,
                    c1.Info1,
                    c1.MasterTable.Info,
                    c1.LookupTable1.Description1,
                    db.LookupTable2.Where(x => x.LookupId2 == c1.MasterTable.ChildTable2.OrderByDescending(y=>y.ChildId2).FirstOrDefault().LookupId2).FirstOrDefault().Description2,
                    db.LookupTable2.Where(x => x.LookupId2 == c1.MasterTable.ChildTable2.OrderByDescending(y=>y.ChildId2).FirstOrDefault().LookupId2).FirstOrDefault().Description3
                }).ToList();

and it generate this sql query

SELECT 
[Filter3].[ChildId1] AS [ChildId1], 
[Filter3].[Info1] AS [Info1], 
[Filter3].[Info] AS [Info], 
[Filter3].[Description1] AS [Description1], 
[Limit2].[Description2] AS [Description2], 
[Limit4].[Description3] AS [Description3]
FROM    (SELECT [Extent1].[ChildId1] AS [ChildId1], [Extent1].[MasterId] AS [MasterId1], [Extent1].[Info1] AS [Info1], [Extent2].[Info] AS [Info], [Extent3].[Description1] AS [Description1]
    FROM   [dbo].[ChildTable1] AS [Extent1]
    INNER JOIN [dbo].[MasterTable] AS [Extent2] ON [Extent1].[MasterId] = [Extent2].[MasterId]
    INNER JOIN [dbo].[LookupTable1] AS [Extent3] ON [Extent1].[LookupId1] = [Extent3].[LookupId1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM ( SELECT 
            [Extent4].[MasterId] AS [K1], 
            MAX([Extent4].[ChildId1]) AS [A1]
            FROM [dbo].[ChildTable1] AS [Extent4]
            WHERE [Extent4].[ExtraId] IN (1, 2, 3)
            GROUP BY [Extent4].[MasterId]
        )  AS [GroupBy1]
        WHERE [GroupBy1].[A1] = [Extent1].[ChildId1]
    ) ) AS [Filter3]
OUTER APPLY  (SELECT TOP (1) 
    [Extent5].[Description2] AS [Description2]
    FROM  [dbo].[LookupTable2] AS [Extent5]
    INNER JOIN  (SELECT TOP (1) [Project2].[LookupId2] AS [LookupId2]
        FROM ( SELECT 
            [Extent6].[ChildId2] AS [ChildId2], 
            [Extent6].[LookupId2] AS [LookupId2]
            FROM [dbo].[ChildTable2] AS [Extent6]
            WHERE [Filter3].[MasterId1] = [Extent6].[MasterId]
        )  AS [Project2]
        ORDER BY [Project2].[ChildId2] DESC ) AS [Limit1] ON [Extent5].[LookupId2] = [Limit1].[LookupId2] ) AS [Limit2]
OUTER APPLY  (SELECT TOP (1) 
    [Extent7].[Description3] AS [Description3]
    FROM  [dbo].[LookupTable2] AS [Extent7]
    INNER JOIN  (SELECT TOP (1) [Project4].[LookupId2] AS [LookupId2]
        FROM ( SELECT 
            [Extent8].[ChildId2] AS [ChildId2], 
            [Extent8].[LookupId2] AS [LookupId2]
            FROM [dbo].[ChildTable2] AS [Extent8]
            WHERE [Filter3].[MasterId1] = [Extent8].[MasterId]
        )  AS [Project4]
        ORDER BY [Project4].[ChildId2] DESC ) AS [Limit3] ON [Extent7].[LookupId2] = [Limit3].[LookupId2] ) AS [Limit4]

my question is simple, how could i optimize this linq query?

I think I found how

var query = (from c1 in db.ChildTable1
             join c2 in db.ChildTable2 on c1.MasterId equals c2.MasterId
             let t1 = db.ChildTable1.Where(x => x.MasterId == c2.MasterId).GroupBy(x => x.MasterId).Select(x => x.Max(y => y.ChildId1))
             let t2 = db.ChildTable2.Where(x => x.MasterId == c2.MasterId).GroupBy(x => x.MasterId).Select(x => x.Max(y => y.ChildId2))
             where value.Contains(c1.ExtraId) &&  t1.Contains(c1.ChildId1) && t2.Contains(c2.ChildId2)

             select new
             {
                 c1.ChildId1,
                 c1.MasterTable.Info,
                 c1.Info1,
                 c2.Info2,
                 c1.LookupTable1.Description1,
                 c2.LookupTable2.Description2,
                 c2.LookupTable2.Description3
             }).ToList();

which does (pretty similar to the original sql query)

SELECT 
[Extent1].[ChildId1] AS [ChildId1], 
[Extent3].[Info] AS [Info], 
[Extent1].[Info1] AS [Info1], 
[Extent2].[Info2] AS [Info2], 
[Extent4].[Description1] AS [Description1], 
[Extent5].[Description2] AS [Description2], 
[Extent5].[Description3] AS [Description3]
FROM     [dbo].[ChildTable1] AS [Extent1]
INNER JOIN [dbo].[ChildTable2] AS [Extent2] ON [Extent1].[MasterId] = [Extent2].[MasterId]
INNER JOIN [dbo].[MasterTable] AS [Extent3] ON [Extent1].[MasterId] = [Extent3].[MasterId]
INNER JOIN [dbo].[LookupTable1] AS [Extent4] ON [Extent1].[LookupId1] = [Extent4].[LookupId1]
INNER JOIN [dbo].[LookupTable2] AS [Extent5] ON [Extent2].[LookupId2] = [Extent5].[LookupId2]
WHERE ([Extent1].[ExtraId] IN (1, 2, 3)) AND ( EXISTS (SELECT 
    1 AS [C1]
    FROM ( SELECT 
        [Extent6].[MasterId] AS [K1], 
        MAX([Extent6].[ChildId1]) AS [A1]
        FROM [dbo].[ChildTable1] AS [Extent6]
        WHERE [Extent6].[MasterId] = [Extent2].[MasterId]
        GROUP BY [Extent6].[MasterId]
    )  AS [GroupBy1]
    WHERE [GroupBy1].[A1] = [Extent1].[ChildId1]
)) AND ( EXISTS (SELECT 
    1 AS [C1]
    FROM ( SELECT 
        [Extent7].[MasterId] AS [K1], 
        MAX([Extent7].[ChildId2]) AS [A1]
        FROM [dbo].[ChildTable2] AS [Extent7]
        WHERE [Extent7].[MasterId] = [Extent2].[MasterId]
        GROUP BY [Extent7].[MasterId]
    )  AS [GroupBy2]
    WHERE [GroupBy2].[A1] = [Extent2].[ChildId2]
))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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