更好的linq多重连接方式?

时间:2009-05-21 04:35:27

标签: vb.net linq linq-to-sql

以下是我要做的事情:

我有三个表,清单,详细信息和billingJournal

每个清单都有详细信息,可能是billingJournal条目,如果有,它有字段recordType = 1那么billingJournal.amount是结算金额,我也需要它在我的网格中。

我目前正在做两个步骤:

  1. 使用普通联接将清单及其详细信息汇总在一起,我将返回一个简单的数据网格视图,其中包含基于用户选择的日期范围的附加代码。

  2. 然后我可以通过循环遍历数据网格。我设置循环来检查datagrid的每一行,读取清单号然后在billingJournal表中执行linq查找。如果匹配,它将从billingJournal表中读取数据并获取值并将其存储在datagrids当前行中。 IE在查询billingJournal中的每个清单后,如果有一个匹配的清单,其record_type为1(计费金额),那么我可以做一个简单的替换,如:

  3. BillingReportDataGrid(“amount”,1).Value = queryResult

    我想知道的是,有没有办法在我的主要linq查询中完成所有这些操作?或者,除了我的方式之外,还有更好的方法吗?

    我正在使用一个名为reportData的类,因此我可以按名称访问列。

    我试图玩左连接,但似乎无法得到它。

    谢谢 -

    - 乔

      Dim query = From detail In db.details _
                    Where detail.InboundDate >= CType(MonthCalendar1.SelectionStart, DateTime) _
                    And detail.InboundDate <= CType(MonthCalendar1.SelectionEnd, DateTime).AddHours(23).AddMinutes(59) _
                    Join mainfest In db.Manifests On mainfest.ManifestID Equals detail.MainID _
                    Select New reportData With {.Amount = Nothing, .ManifestID = mainfest.ManifestID, .InboundDate = detail.InboundDate}
    

3 个答案:

答案 0 :(得分:2)

以下是Rick在LINQ中模拟外连接时所讨论的内容的示例。我的VB.Net很生疏,但我知道这在C#非常好用:)

Dim query = From detail In db.details _
                Where detail.InboundDate >= CType(MonthCalendar1.SelectionStart, DateTime) _
                And detail.InboundDate <= CType(MonthCalendar1.SelectionEnd, DateTime).AddHours(23).AddMinutes(59) _
                Join mainfest In db.Manifests On mainfest.ManifestID Equals detail.MainID into mainfestjoin _
                From submj in manifestjoin.DefaultIfEmpty()
                Select New reportData With { _
                                .Amount = Nothing, _
                                .ManifestID = If submj <> Nothing Then mainfest.ManifestID Else 0 EndIf, _
                                .InboundDate = detail.InboundDate}

答案 1 :(得分:1)

您想要的内容基本上是您的billingJournal表的外部联接。你所追求的是一个名为DefaultIfEmpty的运算符。我无法发布链接,但如果您在Google上搜索“模拟外部加入LINQ”,您应该很快就会看到一个示例(很明显已经解决了这个问题)。

答案 2 :(得分:0)

解决方案:使用Let来分配一个变量以及一个嵌入式if语句似乎可以解决问题(感谢来自Experts Exchange的Fernando提供有用的产品......)

Dim query = From detail In db.details _
            Where detail.InboundDate >= CType(MonthCalendar1.SelectionStart, DateTime) _
            And detail.InboundDate <= CType(MonthCalendar1.SelectionEnd, DateTime).AddHours(23).AddMinutes(59) _
            Join mainfest In db.Manifests On mainfest.ManifestID Equals detail.MainID _
            Let BillingQuery = (From b In db.Billings _
                                Where b.ManifestID = mainfest.ManifestID _
                                Order By b.RecordCreationDate Descending _
                                Select b).First.Amount _
            Let BillingAmount = If(BillingQuery IsNot Nothing, Convert.ToDecimal(BillingQuery), Convert.ToDecimal(0.0)) _
            Select New reportData With {.olderDataExists = Nothing, _
                                        .Amount = Convert.ToDecimal(BillingAmount), _
                                        .ManifestID = mainfest.ManifestID, _
                                        .InboundDate = detail.InboundDate}