我在使用下面的代码时遇到问题。它说'结果'是一种表达类型'?'。这不是集合类型

时间:2016-09-09 16:39:43

标签: vb.net visual-studio linq inner-join

我遇到以下代码的问题。它说'结果'是一种表达类型'?'。这不是集合类型。还有我的" =" CInt(table1(ComboBox1.SelectedItem))= CInt(table2(ComboBox2.SelectedItem))之间的符号是' Equals'预期。任何帮助都会很棒,谢谢!不确定table1和table2是否是正确的语法......

Dim tt As New DataTable()
tt = DtSet1.Tables(0)

Dim rr As New DataTable()
rr = DtSet2.Tables(0)

Dim DTA As New DataTable()
DTA.Columns.Add("Account", GetType(Integer))
DTA.Columns.Add("First", GetType(String))
DTA.Columns.Add("Last", GetType(String))
DTA.Columns.Add("Code", GetType(String))

Dim DTB As New DataTable()
DTB.Columns.Add("Code", GetType(String))
DTB.Columns.Add("Amount", GetType(Integer))

For g As Integer = 1 To 6
    Dim row As DataRow = DTA.NewRow()
    row("Account") = g
    row("First") = 10 + g
    row("Last") = 20 + g
    row("Code") = 30 + g
    DTA.Rows.Add(row)

    row = DTB.NewRow()
    row("Code") = 40 + g
    row("Amount") = 50 + g
    DTB.Rows.Add(row)
Next

Dim results = _
    From table1 In DTA.AsEnumerable() Join table2 In DTB.AsEnumerable() _
        On CInt(table1(ComboBox1.SelectedItem)) = CInt(table2(ComboBox2.SelectedItem)) _
    New With { _
        Key .Account = CInt(tt("Account")), _
        Key .First = CInt(tt("First")), _
        Key .Last = CInt(tt("Last")), _
        Key .Offer = CInt(tt("Code")), _
        Key .Amount = CInt(rr("Amount")) _
    }

For Each item As var In results
    Console.WriteLine([String].Format("Account = {0}, First = {1}, Last = {2}, Code = {3}, Amount = {4}", item.Account, item.First, item.Last, item.Code, item.Amount))
Next

Console.ReadLine()

2 个答案:

答案 0 :(得分:0)

发布的代码无法编译 - 您确定实际版本是否相同?

在这里。 LINQ语法错误。首先,在Join条款中,必须使用Equals关键字,而不是=符号。接下来CInt()函数放错位置 - 它应该应用于ComboBox1.SelectedItem以生成一个整数,该整数将被视为列索引。最后,您需要使用Select关键字来指定select子句。就在New关键字之前。因此,您会在IEnumerable(Of <anonymous type>)变量中获得results

稍后在For ... Next循环声明中,松开&#34; As var&#34;。 item类型将根据用途推断。

简单的LINQ查询很难。他们需要实践和理论知识才能掌握。幸运的是有LINQ扩展方法。它们实现的基本相同,但方式不同。如果它们按顺序执行,则代码变得更具可读性,并且会向命令式方法关闭。

E.g。上面的LINQ查询可以重写如下:

Dim results = DTA.AsEnumerable().Join(DTB.AsEnumerable(), 
        Function(r1) r1(CInt(ComboBox1.SelectedItem)), ' The key selector for the LEFT row
        Function(r2) r2(CInt(ComboBox2.SelectedItem)), ' The key selector for the RIGHT row
        Function(tt, rr) New With { 
            Key .Account = CInt(tt("Account")), _
            Key .First = CInt(tt("First")), _
            Key .Last = CInt(tt("Last")), _
            Key .Offer = CInt(tt("Code")), _
            Key .Amount = CInt(rr("Amount")) _
        } ' Result selector

答案 1 :(得分:0)

关于数据的来源,您的问题相当模糊。

我在表单上有两个ComboBox和一个Button的例子;它创建自己的样本数据:

 @ManyToMany(mappedBy = "films")
 @JoinTable(name="actor_films", joinColumns=@JoinColumn(name="film_id"), inverseJoinColumns=@JoinColumn(name="actor_id"))  

如果在两个组合框中选择“代码”,则会提供此输出:

Option Infer On
Option Strict On

Public Class Form1

    ' a method to show a datatable
    Sub PrintDataTable(dt As DataTable)
        Dim columnWidth = 10
        Dim separator = New String("="c, columnWidth * dt.Columns.Count)
        Console.WriteLine(separator)
        Console.WriteLine(dt.TableName)

        For Each n As DataColumn In dt.Columns
            Console.Write(n.ColumnName.PadLeft(columnWidth))
        Next
        Console.WriteLine()

        For Each r As DataRow In dt.Rows
            For i = 0 To dt.Columns.Count - 1
                Console.Write(r.Item(i).ToString().PadLeft(columnWidth, " "c))
            Next
            Console.WriteLine()
        Next
        Console.WriteLine(separator)

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' create some test data
        Dim DTA As New DataTable("DTA")
        DTA.Columns.Add("Account", GetType(Integer))
        DTA.Columns.Add("First", GetType(String))
        DTA.Columns.Add("Last", GetType(String))
        DTA.Columns.Add("Code", GetType(String))

        Dim DTB As New DataTable("DTB")
        DTB.Columns.Add("Code", GetType(String))
        DTB.Columns.Add("Amount", GetType(Integer))

        ' add values of test data where some values of "Code" are equal
        For g As Integer = 1 To 6
            Dim row As DataRow = DTA.NewRow()
            row("Account") = g
            row("First") = (10 + g).ToString()
            row("Last") = (20 + g).ToString()
            row("Code") = (30 + g).ToString()
            DTA.Rows.Add(row)

            row = DTB.NewRow()
            row("Code") = (30 + CInt(g Mod 4)).ToString()
            row("Amount") = (50 + g).ToString()
            DTB.Rows.Add(row)
        Next

        ' show the data for visual verification
        PrintDataTable(DTA)
        PrintDataTable(DTB)

        ' N.B. for the test data it is necessary to select "Code" in each ComboBox
        Dim colToMatchA = CStr(ComboBox1.SelectedItem)
        Dim colToMatchB = CStr(ComboBox2.SelectedItem)

        Console.WriteLine($"A: {colToMatchA} B: {colToMatchB}")

        ' N.B. it is required that the column data have a .ToString() method which is
        ' unique for each possible value. Note that the number 0 will match the string "0" etc.
        Dim result = From a In DTA
                     Join b In DTB
                     On a.Item(colToMatchA).ToString() Equals b.Item(colToMatchB).ToString()
                     Select New With {.Account = a("Account"), .CodeA = a("Code"), .Amount = b("Amount")}

        For Each r In result
            Console.WriteLine(r.ToString())
        Next

        Console.WriteLine("Done.")

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim colsA = {"Account", "First", "Last", "Code"}
        Dim colsB = {"Code", "Amount"}
        ComboBox1.DataSource = colsA
        ComboBox2.DataSource = colsB

    End Sub

End Class