与Linq一起在EF-Core中进行内部联接和外部联接

时间:2019-03-01 13:48:07

标签: c# sql linq .net-core entity-framework-core

我正在尝试将以下SQL转换为c#(。net核心2.1和EF核心2.2)中的Linq查询

SELECT  TD.*, RD.Match
        FROM    TransactionDetail TD
                INNER JOIN dbo.Measure M ON M.InternalID = TD.MetricCode
                LEFT OUTER JOIN (
                    SELECT tmp.ID, tmp.ReportingDate, 1 AS Match
                    FROM tmp
                ) AS RD ON RD.ID = M.Frequency AND RD.ReportingDate = TD.ReportingDate
        WHERE   RD.Match IS NULL AND
                TD.BatchID = @batchID AND
                NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'NRD') AND
                NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'RDP') AND
                NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'RDF')

有人可以帮助我如何先进行内部联接,然后再进行左外部联接?

我已经走了,

var IQ1 = (from TD in IngestionHubContext.TransactionDetail
                   join M in  ModelHospitalPreviewContext.Measure on TD.MetricCode equals M.InternalId 
                   join R in RD.DefaultIfEmpty on new {ID = M.Frequency, TD.ReportingDate} equals new { R.ID, R.ReportingDate} into J
                   //????? 

任何帮助或建议都会受到赞赏。

谢谢。

2 个答案:

答案 0 :(得分:2)

在下面,您可以使用单个DbContext查找示例的简化版本:

var batchId = 123;

var transactionDetailFailureReasonsToExcludeQuery =
    from r in dbContext.TransactionDetailFailureReasons
    where
        r.TransactionFailureReasonID == "NRD" ||
        r.TransactionFailureReasonID == "RDP" ||
        r.TransactionFailureReasonID == "RDF"
    select r.TransactionDetailID;

var query =
    from td in dbContext.TransactionDetail
    join m in dbContext.Measure on td.MetricCode equals m.InternalID
    join rd in dbContext.Tmp on new { m.Frequency, td.ReportingDate } equals new { Frequency = rd.ID, rd.ReportingDate } into rdItems
    from rd in rdItems.DefaultIfEmpty()
    where
        rd == null &&
        td.BatchID == batchId &&
        transactionDetailFailureReasonsToExcludeQuery.Contains(td.ID) == false
    select td;

现在,您需要对其进行更新,以对实体使用正确的DbContext

希望这会有所帮助。

答案 1 :(得分:0)

在Ef Core中,您可以使用SQL查询,而不必将其更改为Linq查询。 目前,Ef Core不支持将所有Linq操作转换为SQL。因此,将SQL转换为Linq可能会导致client-side evaluation

您可以在此处找到详细信息:Raw SQL

请使用您的模型值更改“选择”查询。

var transactionDetails = IngestionHubContext.TransactionDetail.FromSql("SELECT  TD.*, RD.Match
        FROM    TransactionDetail TD
                INNER JOIN dbo.Measure M ON M.InternalID = TD.MetricCode
                LEFT OUTER JOIN (
                    SELECT tmp.ID, tmp.ReportingDate, 1 AS Match
                    FROM tmp
                ) AS RD ON RD.ID = M.Frequency AND RD.ReportingDate = TD.ReportingDate
        WHERE   RD.Match IS NULL AND
                TD.BatchID = @batchID AND
                NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'NRD') AND
                NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'RDP') AND
                NOT EXISTS (SELECT TransactionFailureReasonID FROM TransactionDetailFailureReasons R WHERE R.TransactionDetailID = TD.ID and R.TransactionFailureReasonID = 'RDF')", batchIDParameter);

我希望这会有所帮助。