简体   繁体   English

INNER JOINS 和 LEFT JOINS 的 EF Core 难度

[英]EF Core difficulty with INNER JOINS and LEFT JOINS

I am trying to retrieve some data from a very big database.我正在尝试从一个非常大的数据库中检索一些数据。 In order to retrieve it I need to get some data from within 6 inner joins.为了检索它,我需要从 6 个内部连接中获取一些数据。 The following options is what I tried already:以下选项是我已经尝试过的:

Option 1 Using EF Core en ThenInclude选项 1 使用 EF Core en ThenInclude

    var enquiry = await _context.Enquiries
        .Where(e => e.Id == id)
        .Include(e => e.EnqPartJobs.Where(ej => ej.RecordStateId == 0))
            .ThenInclude(ej => ej.AnswerGrpBatch)
                .ThenInclude(agb => agb.AnswerGrps)
                    .ThenInclude(ag => ag.EnqPropResults)
                        .ThenInclude(epr => epr.EnqPropResultDevs)
                            .ThenInclude(epr => epr.Deviation)
        .ToListAsync();

The advantage of this method is that it will map nicely in a Enquiry class with a list of AnswerGrpBatches.这种方法的优点是它可以很好地在带有 AnswerGrpBatches 列表的查询 class 中使用 map。 Btw I did not name these classes this is just how the database looks.顺便说一句,我没有命名这些类,这就是数据库的外观。

When looking at the query it is the following:查看查询时,如下所示:

SELECT [e].[SID], [e].[FK_CRMPartner_SID], [e].[FK_Certificate_SID], [e].[createDate], [e].[displayDate], [e].[extID], [e].[finishDate], [e].[fixedGenId], [e].[aName], [t2].[SID], [t2].[FK_Enquiry_SID], [t2].[aName], [t2].[FK_RecordState_SID], [t2].[remark], [t2].[validFrom], [t2].[validTo], [t2].[SID0], [t2].[FK_EnqPartJob_SID], [t2].[FK_RecordState_SID0], [t2].[SID1], [t2].[FK_AnswerGrpBatch_SID], [t2].[FK_RecordState_SID1], [t2].[SID00], [t2].[FK_AnswerGrp_SID], [t2].[FK_EnqPropertyForm_SID], [t2].[FK_PossResult_SID], [t2].[FK_RecordState_SID00], [t2].[value], [t2].[SID000], [t2].[FK_Deviation_SID], [t2].[FK_EnqPropResult_SID], [t2].[SID0000], [t2].[aDescription], [t2].[aName0]
FROM [Enquiry] AS [e]
LEFT JOIN (
    SELECT [e0].[SID], [e0].[FK_Enquiry_SID], [e0].[aName], [e0].[FK_RecordState_SID], [e0].[remark], [e0].[validFrom], [e0].[validTo], [a].[SID] AS [SID0], [a].[FK_EnqPartJob_SID], [a].[FK_RecordState_SID] AS [FK_RecordState_SID0], [t1].[SID] AS [SID1], [t1].[FK_AnswerGrpBatch_SID], [t1].[FK_RecordState_SID] AS [FK_RecordState_SID1], [t1].[SID0] AS [SID00], [t1].[FK_AnswerGrp_SID], [t1].[FK_EnqPropertyForm_SID], [t1].[FK_PossResult_SID], [t1].[FK_RecordState_SID0] AS [FK_RecordState_SID00], [t1].[value], [t1].[SID00] AS [SID000], [t1].[FK_Deviation_SID], [t1].[FK_EnqPropResult_SID], [t1].[SID000] AS [SID0000], [t1].[aDescription], [t1].[aName] AS [aName0]
    FROM [EnqPartJob] AS [e0]
    LEFT JOIN [AnswerGrpBatch] AS [a] ON [e0].[SID] = [a].[FK_EnqPartJob_SID]
    LEFT JOIN (
        SELECT [a0].[SID], [a0].[FK_AnswerGrpBatch_SID], [a0].[FK_RecordState_SID], [t0].[SID] AS [SID0], [t0].[FK_AnswerGrp_SID], [t0].[FK_EnqPropertyForm_SID], [t0].[FK_PossResult_SID], [t0].[FK_RecordState_SID] AS [FK_RecordState_SID0], [t0].[value], [t0].[SID0] AS [SID00], [t0].[FK_Deviation_SID], [t0].[FK_EnqPropResult_SID], [t0].[SID00] AS [SID000], [t0].[aDescription], [t0].[aName]
        FROM [AnswerGrp] AS [a0]
        LEFT JOIN (
            SELECT [e1].[SID], [e1].[FK_AnswerGrp_SID], [e1].[FK_EnqPropertyForm_SID], [e1].[FK_PossResult_SID], [e1].[FK_RecordState_SID], [e1].[value], [t].[SID] AS [SID0], [t].[FK_Deviation_SID], [t].[FK_EnqPropResult_SID], [t].[SID0] AS [SID00], [t].[aDescription], [t].[aName]
            FROM [EnqPropResult] AS [e1]
            LEFT JOIN (
                SELECT [e2].[SID], [e2].[FK_Deviation_SID], [e2].[FK_EnqPropResult_SID], [d].[SID] AS [SID0], [d].[aDescription], [d].[aName]
                FROM [EnqPropResultDev] AS [e2]
                INNER JOIN [Deviation] AS [d] ON [e2].[FK_Deviation_SID] = [d].[SID]
            ) AS [t] ON [e1].[SID] = [t].[FK_EnqPropResult_SID]
        ) AS [t0] ON [a0].[SID] = [t0].[FK_AnswerGrp_SID]
    ) AS [t1] ON [a].[SID] = [t1].[FK_AnswerGrpBatch_SID]
    WHERE [e0].[FK_RecordState_SID] = 0
) AS [t2] ON [e].[SID] = [t2].[FK_Enquiry_SID]
WHERE [e].[SID] = 1790797

But it needs to be one of these 2 options:但它必须是以下两个选项之一:

using a IS NOT NULL statement but I cannot figure out how to make this one beceause it is deep inside different classes.使用 IS NOT NULL 语句,但我无法弄清楚如何制作这个语句,因为它在不同的类中很深。

SELECT [e].[SID], [e].[FK_CRMPartner_SID], [e].[FK_Certificate_SID], [e].[createDate], [e].[displayDate], [e].[extID], [e].[finishDate], [e].[fixedGenId], [e].[aName], [t2].[SID], [t2].[FK_Enquiry_SID], [t2].[aName], [t2].[FK_RecordState_SID], [t2].[remark], [t2].[validFrom], [t2].[validTo], [t2].[SID0], [t2].[FK_EnqPartJob_SID], [t2].[FK_RecordState_SID0], [t2].[SID1], [t2].[FK_AnswerGrpBatch_SID], [t2].[FK_RecordState_SID1], [t2].[SID00], [t2].[FK_AnswerGrp_SID], [t2].[FK_EnqPropertyForm_SID], [t2].[FK_PossResult_SID], [t2].[FK_RecordState_SID00], [t2].[value], [t2].[SID000], [t2].[FK_Deviation_SID], [t2].[FK_EnqPropResult_SID], [t2].[SID0000], [t2].[aDescription], [t2].[aName0]
FROM [Enquiry] AS [e]
LEFT JOIN (
    SELECT [e0].[SID], [e0].[FK_Enquiry_SID], [e0].[aName], [e0].[FK_RecordState_SID], [e0].[remark], [e0].[validFrom], [e0].[validTo], [a].[SID] AS [SID0], [a].[FK_EnqPartJob_SID], [a].[FK_RecordState_SID] AS [FK_RecordState_SID0], [t1].[SID] AS [SID1], [t1].[FK_AnswerGrpBatch_SID], [t1].[FK_RecordState_SID] AS [FK_RecordState_SID1], [t1].[SID0] AS [SID00], [t1].[FK_AnswerGrp_SID], [t1].[FK_EnqPropertyForm_SID], [t1].[FK_PossResult_SID], [t1].[FK_RecordState_SID0] AS [FK_RecordState_SID00], [t1].[value], [t1].[SID00] AS [SID000], [t1].[FK_Deviation_SID], [t1].[FK_EnqPropResult_SID], [t1].[SID000] AS [SID0000], [t1].[aDescription], [t1].[aName] AS [aName0]
    FROM [EnqPartJob] AS [e0]
    LEFT JOIN [AnswerGrpBatch] AS [a] ON [e0].[SID] = [a].[FK_EnqPartJob_SID]
    LEFT JOIN (
        SELECT [a0].[SID], [a0].[FK_AnswerGrpBatch_SID], [a0].[FK_RecordState_SID], [t0].[SID] AS [SID0], [t0].[FK_AnswerGrp_SID], [t0].[FK_EnqPropertyForm_SID], [t0].[FK_PossResult_SID], [t0].[FK_RecordState_SID] AS [FK_RecordState_SID0], [t0].[value], [t0].[SID0] AS [SID00], [t0].[FK_Deviation_SID], [t0].[FK_EnqPropResult_SID], [t0].[SID00] AS [SID000], [t0].[aDescription], [t0].[aName]
        FROM [AnswerGrp] AS [a0]
        LEFT JOIN (
            SELECT [e1].[SID], [e1].[FK_AnswerGrp_SID], [e1].[FK_EnqPropertyForm_SID], [e1].[FK_PossResult_SID], [e1].[FK_RecordState_SID], [e1].[value], [t].[SID] AS [SID0], [t].[FK_Deviation_SID], [t].[FK_EnqPropResult_SID], [t].[SID0] AS [SID00], [t].[aDescription], [t].[aName]
            FROM [EnqPropResult] AS [e1]
            LEFT JOIN (
                SELECT [e2].[SID], [e2].[FK_Deviation_SID], [e2].[FK_EnqPropResult_SID], [d].[SID] AS [SID0], [d].[aDescription], [d].[aName]
                FROM [EnqPropResultDev] AS [e2]
                INNER JOIN [Deviation] AS [d] ON [e2].[FK_Deviation_SID] = [d].[SID]
            ) AS [t] ON [e1].[SID] = [t].[FK_EnqPropResult_SID]
        ) AS [t0] ON [a0].[SID] = [t0].[FK_AnswerGrp_SID]
    ) AS [t1] ON [a].[SID] = [t1].[FK_AnswerGrpBatch_SID]
    WHERE [e0].[FK_RecordState_SID] = 0
) AS [t2] ON [e].[SID] = [t2].[FK_Enquiry_SID]
WHERE [e].[SID] = 1790797 AND [t2].[SID000] IS NOT NULL

Forcing INNER JOINS:强制 INNER JOINS:

SELECT [e].[SID], [e].[FK_CRMPartner_SID], [e].[FK_Certificate_SID], [e].[createDate], [e].[displayDate], [e].[extID], [e].[finishDate], [e].[fixedGenId], [e].[aName], [t2].[SID], [t2].[FK_Enquiry_SID], [t2].[aName], [t2].[FK_RecordState_SID], [t2].[remark], [t2].[validFrom], [t2].[validTo], [t2].[SID0], [t2].[FK_EnqPartJob_SID], [t2].[FK_RecordState_SID0], [t2].[SID1], [t2].[FK_AnswerGrpBatch_SID], [t2].[FK_RecordState_SID1], [t2].[SID00], [t2].[FK_AnswerGrp_SID], [t2].[FK_EnqPropertyForm_SID], [t2].[FK_PossResult_SID], [t2].[FK_RecordState_SID00], [t2].[value], [t2].[SID000], [t2].[FK_Deviation_SID], [t2].[FK_EnqPropResult_SID], [t2].[SID0000], [t2].[aDescription], [t2].[aName0]
FROM [Enquiry] AS [e]
LEFT JOIN (
    SELECT [e0].[SID], [e0].[FK_Enquiry_SID], [e0].[aName], [e0].[FK_RecordState_SID], [e0].[remark], [e0].[validFrom], [e0].[validTo], [a].[SID] AS [SID0], [a].[FK_EnqPartJob_SID], [a].[FK_RecordState_SID] AS [FK_RecordState_SID0], [t1].[SID] AS [SID1], [t1].[FK_AnswerGrpBatch_SID], [t1].[FK_RecordState_SID] AS [FK_RecordState_SID1], [t1].[SID0] AS [SID00], [t1].[FK_AnswerGrp_SID], [t1].[FK_EnqPropertyForm_SID], [t1].[FK_PossResult_SID], [t1].[FK_RecordState_SID0] AS [FK_RecordState_SID00], [t1].[value], [t1].[SID00] AS [SID000], [t1].[FK_Deviation_SID], [t1].[FK_EnqPropResult_SID], [t1].[SID000] AS [SID0000], [t1].[aDescription], [t1].[aName] AS [aName0]
    FROM [EnqPartJob] AS [e0]
    LEFT JOIN [AnswerGrpBatch] AS [a] ON [e0].[SID] = [a].[FK_EnqPartJob_SID]
    LEFT JOIN (
        SELECT [a0].[SID], [a0].[FK_AnswerGrpBatch_SID], [a0].[FK_RecordState_SID], [t0].[SID] AS [SID0], [t0].[FK_AnswerGrp_SID], [t0].[FK_EnqPropertyForm_SID], [t0].[FK_PossResult_SID], [t0].[FK_RecordState_SID] AS [FK_RecordState_SID0], [t0].[value], [t0].[SID0] AS [SID00], [t0].[FK_Deviation_SID], [t0].[FK_EnqPropResult_SID], [t0].[SID00] AS [SID000], [t0].[aDescription], [t0].[aName]
        FROM [AnswerGrp] AS [a0]
        INNER JOIN (
            SELECT [e1].[SID], [e1].[FK_AnswerGrp_SID], [e1].[FK_EnqPropertyForm_SID], [e1].[FK_PossResult_SID], [e1].[FK_RecordState_SID], [e1].[value], [t].[SID] AS [SID0], [t].[FK_Deviation_SID], [t].[FK_EnqPropResult_SID], [t].[SID0] AS [SID00], [t].[aDescription], [t].[aName]
            FROM [EnqPropResult] AS [e1]
            INNER JOIN (
                SELECT [e2].[SID], [e2].[FK_Deviation_SID], [e2].[FK_EnqPropResult_SID], [d].[SID] AS [SID0], [d].[aDescription], [d].[aName]
                FROM [EnqPropResultDev] AS [e2]
                INNER JOIN [Deviation] AS [d] ON [e2].[FK_Deviation_SID] = [d].[SID]
            ) AS [t] ON [e1].[SID] = [t].[FK_EnqPropResult_SID]
        ) AS [t0] ON [a0].[SID] = [t0].[FK_AnswerGrp_SID]
    ) AS [t1] ON [a].[SID] = [t1].[FK_AnswerGrpBatch_SID]
    WHERE [e0].[FK_RecordState_SID] = 0
) AS [t2] ON [e].[SID] = [t2].[FK_Enquiry_SID]
WHERE [e].[SID] = 1790797

The problem is that it will use Left Joins for every Include and ThenInclude except the last one.问题是它将对除最后一个之外的每个 Include 和 ThenInclude 使用左连接。 But this will also retrieve information that I do not need.但这也会检索我不需要的信息。 So I tried to make a LINQ query.所以我尝试进行 LINQ 查询。

Option 2 LINQ选项 2 LINQ

The LINQ query always uses INNER JOINS, so I exactly get what I want from the database. LINQ 查询总是使用 INNER JOINS,所以我完全可以从数据库中得到我想要的。 The only problem is that I have no clue how to map this to an Enquiry class where the INNER JOINS are a list within the Enquiry class.唯一的问题是我不知道如何在查询 class 中查询 map,其中 INNER JOINS 是查询 class 中的列表。 Just like with option 1.就像选项 1 一样。

     var query = from enquiry in _context.Set<Enquiry>()
                 join enqPartJob in _context.Set<EnqPartJob>()
                     on enquiry.Id equals enqPartJob.EnquiryId
                 join answerGrpBatch in _context.Set<AnswerGrpBatch>()
                     on enqPartJob.Id equals answerGrpBatch.EnqPartJobId
                 join answerGrp in _context.Set<AnswerGrp>()
                     on answerGrpBatch.Id equals answerGrp.AnswerGrpBatchId
                 join enqPropResult in _context.Set<EnqPropResult>()
                     on answerGrp.Id equals enqPropResult.AnswerGrpId
                 join enqPropResultDev in _context.Set<EnqPropResultDev>()
                     on enqPropResult.Id equals enqPropResultDev.EnqPropResultId
                 join deviation in _context.Set<Deviation>()
                     on enqPropResultDev.DeviationId equals deviation.Id
                 where enquiry.Id == id
                 select new { enquiry, enqPropResultDev };

And yis I get that there is a reason EFCore uses LEFT JOINS but this is not my datbase so I have to adapt to it.是的,我知道 EFCore 使用 LEFT JOINS 是有原因的,但这不是我的数据库,所以我必须适应它。

Thx to Ivan Stoev who commented this suggestion.感谢 Ivan Stoev,他评论了这个建议。

Starting with Deviation and working my way up to Enquiry did the trick for me.从 Deviation 开始,一直到 Inquiry 为我解决了问题。 The query now looks like this (as you can see it contains INNER JOINS).查询现在看起来像这样(您可以看到它包含 INNER JOINS)。

SELECT [t].[SID], [t].[aDescription], [t].[aName], [t0].[SID], [t0].[FK_Deviation_SID], [t0].[FK_EnqPropResult_SID], [t0].[SID0], [t0].[FK_AnswerGrp_SID], [t0].[FK_EnqPropertyForm_SID], [t0].[FK_PossResult_SID], [t0].[FK_RecordState_SID], [t0].[value], [t0].[SID1], [t0].[FK_AnswerGrpBatch_SID], [t0].[FK_RecordState_SID0], [t0].[SID2], [t0].[FK_EnqPartJob_SID], [t0].[FK_RecordState_SID1], [t0].[SID3], [t0].[FK_Enquiry_SID], [t0].[aName], [t0].[FK_RecordState_SID2], [t0].[remark], [t0].[validFrom], [t0].[validTo], [t0].[SID4], [t0].[FK_CRMPartner_SID], [t0].[FK_Certificate_SID], [t0].[createDate], [t0].[displayDate], [t0].[extID], [t0].[finishDate], [t0].[fixedGenId], [t0].[aName0]
FROM (
    SELECT TOP(1) [d].[SID], [d].[aDescription], [d].[aName]
    FROM [Deviation] AS [d]
    WHERE [d].[SID] = 5038
) AS [t]
LEFT JOIN (
    SELECT [e].[SID], [e].[FK_Deviation_SID], [e].[FK_EnqPropResult_SID], [e0].[SID] AS [SID0], [e0].[FK_AnswerGrp_SID], [e0].[FK_EnqPropertyForm_SID], [e0].[FK_PossResult_SID], [e0].[FK_RecordState_SID], [e0].[value], [a].[SID] AS [SID1], [a].[FK_AnswerGrpBatch_SID], [a].[FK_RecordState_SID] AS [FK_RecordState_SID0], [a0].[SID] AS [SID2], [a0].[FK_EnqPartJob_SID], [a0].[FK_RecordState_SID] AS [FK_RecordState_SID1], [e1].[SID] AS [SID3], [e1].[FK_Enquiry_SID], [e1].[aName], [e1].[FK_RecordState_SID] AS [FK_RecordState_SID2], [e1].[remark], [e1].[validFrom], [e1].[validTo], [e2].[SID] AS [SID4], [e2].[FK_CRMPartner_SID], [e2].[FK_Certificate_SID], [e2].[createDate], [e2].[displayDate], [e2].[extID], [e2].[finishDate], [e2].[fixedGenId], [e2].[aName] AS [aName0]
    FROM [EnqPropResultDev] AS [e]
    INNER JOIN [EnqPropResult] AS [e0] ON [e].[FK_EnqPropResult_SID] = [e0].[SID]
    INNER JOIN [AnswerGrp] AS [a] ON [e0].[FK_AnswerGrp_SID] = [a].[SID]
    INNER JOIN [AnswerGrpBatch] AS [a0] ON [a].[FK_AnswerGrpBatch_SID] = [a0].[SID]
    INNER JOIN [EnqPartJob] AS [e1] ON [a0].[FK_EnqPartJob_SID] = [e1].[SID]
    INNER JOIN [Enquiry] AS [e2] ON [e1].[FK_Enquiry_SID] = [e2].[SID]
    WHERE [e0].[FK_RecordState_SID] = 0
) AS [t0] ON [t].[SID] = [t0].[FK_Deviation_SID]
ORDER BY [t].[SID], [t0].[SID], [t0].[SID0], [t0].[SID1], [t0].[SID2], [t0].[SID3], [t0].[SID4]

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

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