左外连接两个数据表?

时间:2014-01-20 21:16:11

标签: vb.net linq

是否可以修改此LINQ方法以执行左外连接?看看LINQ查询,我已经超越了我的脑袋......

Private Function MergeTables(Of T)(ByVal dtForecast As DataTable, 
                                 ByVal dtDns As DataTable, _
                                 ByVal fieldASelector As Func(Of DataRow, T), _
                                 ByVal fieldBSelector As Func(Of DataRow, T), _
                                 ByVal whereClauseA As Func(Of DataRow, Decimal), _
                                 ByVal whereClauseB As Func(Of DataRow, Decimal))
  Dim test = (From forecast In dtForecast.AsEnumerable() Join dns In dtDns.AsEnumerable() _
              On fieldASelector(forecast) Equals fieldBSelector(dns) _
              Where whereClauseA(forecast) <> 0 And whereClauseB(dns) <> 0 _
            Select New With _
                { _
                    .ProductId = forecast.Field(Of String)("ProductID"), _
                    .Product = forecast.Field(Of String)("ProductName"), _
                    .Account = forecast.Field(Of String)("Account"), _
                    .BrandName = forecast.Field(Of String)("BrandName"), _
                    .CorrugateCost = forecast.Field(Of Decimal)("Corrugate_Cost"), _
                    .f_m1 = forecast.Field(Of Decimal)("f_m1"), _
                    .a_m1 = dns.Field(Of Decimal)("a_m1"), _
                    .f_m2 = forecast.Field(Of Decimal)("f_m2"), _
                    .a_m2 = dns.Field(Of Decimal)("a_m2"), _
                    .f_m3 = forecast.Field(Of Decimal)("f_m3"), _
                    .a_m3 = dns.Field(Of Decimal)("a_m3"), _
                    .f_m4 = forecast.Field(Of Decimal)("f_m4"), _
                    .a_m4 = dns.Field(Of Decimal)("a_m4"), _
                    .f_m5 = forecast.Field(Of Decimal)("f_m5"), _
                    .a_m5 = dns.Field(Of Decimal)("a_m5"), _
                    .f_m6 = forecast.Field(Of Decimal)("f_m6"), _
                    .a_m6 = dns.Field(Of Decimal)("a_m6"), _
                    .f_m7 = forecast.Field(Of Decimal)("f_m7"), _
                    .a_m7 = dns.Field(Of Decimal)("a_m7"), _
                    .f_m8 = forecast.Field(Of Decimal)("f_m8"), _
                    .a_m8 = dns.Field(Of Decimal)("a_m8"), _
                    .f_m9 = forecast.Field(Of Decimal)("f_m9"), _
                    .a_m9 = dns.Field(Of Decimal)("a_m9"), _
                    .f_m10 = forecast.Field(Of Decimal)("f_m10"), _
                    .a_m10 = dns.Field(Of Decimal)("a_m10"), _
                    .f_m11 = forecast.Field(Of Decimal)("f_m11"), _
                    .a_m11 = dns.Field(Of Decimal)("a_m11"), _
                    .f_m12 = forecast.Field(Of Decimal)("f_m12"), _
                    .a_m12 = dns.Field(Of Decimal)("a_m12"), _
                    .f_total = forecast.Field(Of Decimal)("f_total"), _
                    .a_total = dns.Field(Of Decimal)("a_total") _
                }).ToList()

        Return test
    End Function

2 个答案:

答案 0 :(得分:1)

对您的查询使用以下修改以Left Outer Join

    From forecast In dtForecast.AsEnumerable() Group Join dns In dtDns.AsEnumerable() _
    On fieldASelector(forecast) Equals fieldBSelector(dns) Into JoinTable = Group _
    From dns in JoinTable.DefaultIfEmpty()_
    Where whereClauseA(forecast) <> 0 And whereClauseB(dns) <> 0 _

我建议使用此资源来帮助您使用LINQ:101 LINQ Samples。 (特别针对此问题,请转到“LINQ查询示例”&gt;“加入运算符”&gt; Left Outer Join。)

答案 1 :(得分:1)

您可以使用Group Join + DefaultIfEmpty

Dim joined = From forecast In dtForecast.AsEnumerable()
             Group Join dns In dtDns.AsEnumerable()
             On fieldASelector(forecast) Equals fieldBSelector(dns) Into Group
             From x In Group.DefaultIfEmpty
             Where whereClauseA(forecast) <> 0 And whereClauseB(dns) <> 0
             Select New With
              {
                 .ProductId = forecast.Field(Of String)(ProductID),
                 .a_m2 = If(x Is Nothing, New Nullable(Of Decimal), x.Field(Of Decimal)("a_m2"))
              }