【问题标题】:VB.net Linq join on two columnsVB.net Linq 加入两列
【发布时间】:2014-08-07 22:38:46
【问题描述】:

请帮助我。这是我的第一个 LINQ。

我有两个数据表,我需要加入两个字段。

我该怎么做?

我尝试了以下操作,但连接不起作用。 "yk.Field(Of String)("secNo")" 出错,消息是"只能从不带参数的简单或限定名称中推断出匿名类型成员名称"

    Dim dtYk As DataTable = New DataTable("dtYk")
    dtYk.Columns.Add("secNo")
    dtYk.Columns.Add("BomLine")
    dtYk.Rows.Add("EA(1)", 1)
    dtYk.Rows.Add("EA(8)", 17)

    Dim dtIvt As DataTable = New DataTable("dtIvt")
    dtIvt.Columns.Add("secNo")
    dtIvt.Columns.Add("BomLine")
    dtIvt.Columns.Add("PartCode")
    dtIvt.Rows.Add("EA(1)", 1, "TRML07-32-LH-ASSY**")
    dtIvt.Rows.Add("EA(8)", 17, "328")

    ' Create a DataSet. Put both tables in it.
    Dim dsYk As DataSet = New DataSet("dsYk")
    dsYk.Tables.Add(dtYk)

    Dim dsIvt As DataSet = New DataSet("dsIvt")
    dsIvt.Tables.Add(dtIvt)

    Dim LinQuery = From yk In dtYk.AsEnumerable
                   Join ivt In dtIvt.AsEnumerable
                   On New With {yk.Field(Of String)("secNo") , yk.Field(Of String)("BomLine")} Equals New With {ivt.Field(Of String)("secNo") , ivt.Field(Of String)("BomLine")}
                   Select New With {yk.Field(Of String)("secNo") , yk.Field(Of String)("BomLine"),ivt.Field(Of String)("secNo")}

这是一个简单的版本。但这只会连接一个字段并只选择一个表。

Dim LinQuery = From yk In dtYk.AsEnumerable()
                       Join ivt In dtIvt.AsEnumerable()
                       On yk.Field(Of String)("secNo") Equals ivt.Field(Of String)("secNo")
                       Select yk

        Dim dt As New DataTable
        dt = LinQuery.CopyToDataTable

我的目标是加入两个字段,选择应该是 yk.SecNo、yk.BomLine 和 ivt.PartCode。请帮忙。谢谢

【问题讨论】:

    标签: vb.net linq


    【解决方案1】:

    使用And 关键字连接复合键应该可以工作(请参阅MSDN article,“使用复合键执行连接”部分)。快速测试证明了这一点:

    Dim dtYk As New DataTable()
    dtYk.Columns.Add("secNo")
    dtYk.Columns.Add("BomLine")
    dtYk.Rows.Add(1, 3)
    dtYk.Rows.Add(2, 4)
    dtYk.Rows.Add(3, 5)
    
    Dim dtIvt As New DataTable
    dtIvt.Columns.Add("secNo")
    dtIvt.Columns.Add("BomLine")
    dtIvt.Rows.Add(1, 3)
    dtIvt.Rows.Add(2, 5)
    dtIvt.Rows.Add(3, 4)
    Dim LinQuery = From yk In dtYk.AsEnumerable
                   Join ivt In dtIvt.AsEnumerable
                   On yk.Field(Of String)("secNo") Equals ivt.Field(Of String)("secNo") And
                      yk.Field(Of String)("BomLine") Equals ivt.Field(Of String)("BomLine")
                   Select New With {.secNo1 = yk.Field(Of String)("secNo"),
                                     .bomLine = yk.Field(Of String)("BomLine"),
                                     .bomLine2 = ivt.Field(Of String)("BomLine")}
    For Each o As Object In LinQuery
        'the output is only one row :'
        '{ secNo1 = 1, bomLine = 3, bomLine2 = 3 }'
        Console.WriteLine(o)
    Next
    

    关于您收到的错误消息,这意味着您需要手动指定匿名类型的成员字段名称(在上面的示例中的Select clasue 中也有演示)。

    【讨论】:

      【解决方案2】:

      @har07 表明您可以使用 And 加入复合键,这是最好的答案,但如果您想知道为什么匿名类型不起作用,您需要使用 Key 来标记哪个属性用于相等性检查,否则它们通过引用进行比较。因此,以下内容也可以使用,但可读性不如 And 版本。

      Dim LinQuery =
          From yk In dtYk.AsEnumerable()
          Join ivt In dtIvt.AsEnumerable() On
              New With { Key .secNo = yk.Field(Of String)("secNo"), Key .BomLine = yk.Field(Of String)("BomLine") } _
              Equals _
              New With { Key .secNo = ivt.Field(Of String)("secNo"), Key .BomLine = ivt.Field(Of String)("BomLine") }
          Select New With {
              .secNo = yk.Field(Of String)("secNo"),
              .BomLine = yk.Field(Of String)("BomLine"),
              .PartCode = ivt.Field(Of String)("PartCode")
          }
      

      【讨论】:

        【解决方案3】:

        VB.Net LINQ - left outer join between two datatables - limit to one row类似的问题

        忽略一行位。

        您还需要将此作为您的在线加入两个字段

        On yk.Field(Of String)("secNo") 等于 ivt.Field(Of String)("secNo") 和 yk.Field(Of String)("BomLine") 等于 ivt.Field(Of String) ("BomLine")

        【讨论】:

        • 我试过“在 secno 上等于 secno 并且 bomline 等于 bomline”并且不是 LINQ 的正确语法。我相信 AND 在 JOIN 中无效。
        • 所以它不能在 on 语句中使用 and 进行编译?我还会通过定义列类型来帮助 linq。例如Dim myCOl As New DataColumn("SecNo", System.Type.GetType("System.string")) dtYk.Columns.Add(myCOl)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-01
        相关资源
        最近更新 更多