【问题标题】:INNER Join and LEFT OUTER JOIN in EF-Core with Linq使用 Linq 在 EF-Core 中进行 INNER Join 和 LEFT OUTER JOIN
【发布时间】:2019-07-23 13:34:51
【问题描述】:

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

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
                   //????? 

感谢任何帮助或建议。

提前致谢。

【问题讨论】:

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


    【解决方案1】:

    您可以在下面找到示例的简化版本,使用单个 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

    希望这会有所帮助。

    【讨论】:

    • @PUBG - 你的TransactionDetail 类是否有TransactionDetailFailureReasons 的导航属性?这个答案似乎做了你想做的事(而不是回避它),但如果你有一个导航属性,失败原因测试可能会更自然。
    【解决方案2】:

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

    您可以在这里找到详细信息:Raw SQL

    请使用您的模型值更改您的 Select 查询。

    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);
    

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-09-29
      • 2013-05-02
      • 1970-01-01
      • 2015-01-10
      • 2016-10-31
      • 1970-01-01
      • 2018-08-21
      • 2019-09-03
      • 1970-01-01
      相关资源
      最近更新 更多