【问题标题】:Multiple JOINS with Conditions between them : LINQ query多个 JOINS 与它们之间的条件:LINQ 查询
【发布时间】:2019-07-16 17:07:42
【问题描述】:

我正在尝试将 SQL 查询转换为 C# 等效的 LINQ/Lambda,如下所示

SELECT  mv.MeasureID, mv.ProviderID, MAX(mv.ReportingDate) AS mostRecentReportingDate
FROM    (((TransactionDetail AS td
           INNER JOIN #provider AS p ON td.TrustCode = p.Code)
           INNER JOIN #measure AS m ON td.MetricCode = m.InternalID)
           INNER JOIN #measureValue AS mv ON m.ID = mv.MeasureID AND p.ID = mv.ProviderID)
WHERE   td.BatchID = @batchID AND
        td.RowAction = 'A' AND
        (m.Type = 7 OR m.Type = 8) AND
        td.Value <> mv.Value
GROUP BY mv.MeasureID, mv.ProviderID

我卡在这条线上

INNER JOIN #measureValue AS mv ON m.ID = mv.MeasureID AND p.ID = mv.ProviderID)

以下是我目前尝试过的

 var total = (from TD in ingestionHubContext.TransactionDetail
                    join P in provider on TD.TrustCode equals P.Code
                    join M in measure on TD.MetricCode equals M.InternalId
                    join MV in measureValue on M.Id equals MV.MeasureId //and logic to be fixed
                    where TD.BatchId == batchId && TD.RowAction == "A"
                    && (M.Type == 7 || M.Type == 8) && TD.Value != MV.Value
                    group TD by new { MV.MeasureId, MV.ProviderId } into Total
                    select Total);

您能否建议我如何以更好的方式编写此内容?并在我的代码的第 4 行处理带有 AND 条件的 JOIN。

我在下面尝试了它不起作用,因为它们需要匹配(错误在 P.Id)

join MV in measureValue 
on new { M.id, P.Id } equals new { MV.MeasureId, MV.ProviderId }

我还需要帮助来完成MAX(mv.ReportingDate)

非常感谢任何帮助。提前致谢。

【问题讨论】:

    标签: c# sql .net linq lambda


    【解决方案1】:

    当ON子句中有多个字段时,需要使用对象进行比较。 您的 LINQ 查询应编写如下:

        var total = (from TD in ingestionHubContext.TransactionDetail
                            join P in provider on TD.TrustCode equals P.Code
                            join M in measure on TD.MetricCode equals M.InternalId
    // Here is how
                            join MV in measureValue on new {M.Id, P.Id} equals new {MV.MeasureId, MV.ProviderId}
    // the rest is your original where statement
                            where TD.BatchId == batchId && TD.RowAction == "A"
                            && (M.Type == 7 || M.Type == 8) && TD.Value != MV.Value
                            group TD by new { MV.MeasureId, MV.ProviderId } into Total
                            select Total);
    

    【讨论】:

    • 这会给出错误提示“匿名类型不能有多个同名属性”(P.Id)。这正是我被困的地方。你能详细说明你的答案吗?
    • 你得到这个是因为匿名者试图为“P.Id”值命名属性“Id”,但它已经存在于“M.Id”中。如果 M 的 Id 字段名称是 mId,而 P 的 Id 字段名称是 pId,这将正常工作,但由于两个表中的列共享相同的名称,anon 无法处理歧义。这就是为什么您为自己发布的答案new {mId = M.Id, pId = P.Id} 是有效的。
    • 关于如何选择 MAX(mv.ReportingDate) 的任何建议??
    • 感谢 Josh,因为我是在 VS 之外回复的,所以我错过了这两个属性被称为相同的 :)
    • PUBG,当然,看我的单独回答
    【解决方案2】:

    抱歉,我没有看到您的第二个问题。 最终的 LINQ 查询将实现您正在寻找的内容,包括 Max 将是以下语句:

    var query = from td in transactionDetails
                            join p in providers on td.TrustCode equals p.Code
                            join m in measures on td.MetricCode equals m.InternalId
                            join mv in measureValues on new { mId = m.Id, pId = p.Id } equals new { mId = mv.MeasureId, pId = mv.ProviderId }
                            where td.BatchId == batchId && td.RowAction == "A"
                            && (m.Type == 7 || m.Type == 8) && td.Value != mv.Value
                            select new { td, p, m, mv } into queryList
                            group queryList by new { queryList.mv.MeasureId, queryList.mv.ProviderId } into groupedList
                            select new {
                                groupedList.Key.MeasureId,
                                groupedList.Key.ProviderId,
                                mostRecentReportingDate = groupedList.Max(g => g.mv.ReportingDate) };
    

    我为提供者、度量等的集合使用了简化名称,您可以将真正的提供者放在那里。

    此 LINQ 查询将返回您原始 SQL 查询的结果,并将由 SQL Server 尽可能优化,对于 LINQ to DB 的优化,您无能为力...

    祝你好运!

    【讨论】:

    • 感谢以上详细解释。
    【解决方案3】:

    我通过编写如下查询解决了

    join MV in measureValue on new { mID = M.Id, pID = P.Id } equals new {mID = MV.MeasureId, pID = MV.ProviderId }
    

    这允许使用多个表列的条件。

    如果有人可以帮助更有效地重写此内容,我将不胜感激。

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-03
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      • 2013-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多