合并不同类型的数据表列到一个更大的数据表中

5
我有两个独立的数据表,一个是整数类型,一个是字符串类型。两个表的大小均为3x3,并且我想将这两个表简单合并并在datagridview中显示,以便我可以显示一个3x6的datagridview。
以下是示例图片: Two separate datatables 我希望将这两个表组合起来,得到下面的图片所示的结果: Datatables joined
    Dim stringtable As New DataTable
    stringtable.Columns.Add("PK", GetType(Integer))
    stringtable.Columns.Add("Col1", GetType(Integer))
    stringtable.Columns.Add("Col2", GetType(Integer))
    stringtable.Columns.Add("Col3", GetType(Integer))

    stringtable.Rows.Add(1, 1, 1, 1)
    stringtable.Rows.Add(2, 2, 2, 2)
    stringtable.Rows.Add(3, 3, 3, 3)

    Dim primaryKey(1) As DataColumn
    primaryKey(0) = stringtable.Columns("Name")
    stringtable.PrimaryKey = primaryKey

    Dim Inttable As New DataTable
    Inttable.Columns.Add("PK", GetType(Integer))
    Inttable.Columns.Add("ColA", GetType(String))
    Inttable.Columns.Add("ColB", GetType(String))
    Inttable.Columns.Add("ColC", GetType(String))

    Inttable.Rows.Add(1, "A", "A", "A")
    Inttable.Rows.Add(2, "B", "B", "B")
    Inttable.Rows.Add(3, "C", "C", "C")

    primaryKey(0) = Inttable.Columns("Name")
    Inttable.PrimaryKey = primaryKey

    DataGridView2.DataSource = stringtable
    DataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
    DataGridView2.AllowUserToAddRows = False

    DataGridView1.DataSource = Inttable
    DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
    DataGridView1.AllowUserToAddRows = False


    ''This is where I can't figure out what do
    Dim mergedTable As New DataTable
    mergedTable = DataGridView2.DataSource
    mergedTable.Merge(Inttable, False, MissingSchemaAction.Add)

    DataGridView3.DataSource = mergedTable

我尝试过几种方法,但似乎无法做到正确的结果。有时它会用12个空单元格填充6x6 datagridview,而其他时候它会保留一个datatable的值,但将第二个datatable的所有值替换为空白。

编辑 我已经编辑了我的代码,以反映在datatables中添加主键,但是现在对于某些表格,它仍然会用空单元格填充。有人能告诉我为什么datatables不仅仅在主键上合并而不留下空行吗?

enter image description here

2个回答

3
为了合并两个 DataTables,你需要一个共同的列 - 最好/最容易的方法是给它们都添加一个主键列,然后你可以像代码中那样简单地合并它们。
更新: 根据你更新后的代码,你的问题在于你如何定义你的主键...
这里有一些问题:
1. 你用名为PK的列定义了你的主键列,然后你有primaryKey(0) = Inttable.Columns("Name") 这应该是primaryKey(0) = Inttable.Columns("PK") 2. 你把你的 primaryKey 数组定义如下: Dim primaryKey(1) As DataColumn 它应该是:
Dim primaryKey(0) As DataColumn

使其只有一个值(你的方法实际上创建了一个由两个元素组成的数组,因为它是基于零的数组语言)。
修改后的代码应如下所示:
Dim primaryKey(0) As DataColumn
primaryKey(0) = stringtable.Columns("PK")
stringtable.PrimaryKey = primaryKey

虽然这种写法也能达到同样的效果,但我更喜欢以以下方式进行编写:

stringtable.PrimaryKey = {stringtable.Columns("PK")}

为了帮助您,这里是我创建的一些代码,可以实现您想要的功能(不包括DataGridView部分)。
Dim stringtable As New DataTable
stringtable.Columns.Add("PK", GetType(Integer))
stringtable.Columns.Add("Col1", GetType(Integer))
stringtable.Columns.Add("Col2", GetType(Integer))
stringtable.Columns.Add("Col3", GetType(Integer))

stringtable.Rows.Add(1, 1, 1, 1)
stringtable.Rows.Add(2, 2, 2, 2)
stringtable.Rows.Add(3, 3, 3, 3)

stringtable.PrimaryKey = {stringtable.Columns("PK")}

Dim Inttable As New DataTable
Inttable.Columns.Add("PK", GetType(Integer))
Inttable.Columns.Add("ColA", GetType(String))
Inttable.Columns.Add("ColB", GetType(String))
Inttable.Columns.Add("ColC", GetType(String))

Inttable.Rows.Add(1, "A", "A", "A")
Inttable.Rows.Add(2, "B", "B", "B")
Inttable.Rows.Add(3, "C", "C", "C")

Inttable.PrimaryKey = {Inttable.Columns("PK")}

stringtable.Merge(Inttable, False, MissingSchemaAction.AddWithKey)

希望这可以帮到你并且讲解得清楚明白!

我曾经了解过如何将某一列设置为主键,但由于没有共同的列,我希望有比修改所有数据更简单的方法。如果我没错的话,仅仅通过循环遍历所有行来添加一列并不容易吧?这些是示例表格,我的SQL查询生成的数据网格视图要大得多。 - user3334230
@user3334230,我刚刚更新了我的答案 - 希望这样解释得更好/对你有所帮助... - John Bustos
1
谢谢。我太蠢了,从未意识到我使用的是“Name”而不是“PK”。 - user3334230
我知道合并的操作,但是我忘记了主键部分。谢谢! - archangel76

0

使用 LINQ

        Dim intTable As New DataTable
        Dim stringTable As New DataTable

        intTable.Columns.Add("Col1", GetType(Integer))
        intTable.Columns.Add("Col2", GetType(Integer))
        intTable.Columns.Add("Col3", GetType(Integer))

        intTable.Rows.Add(1, 1, 1)
        intTable.Rows.Add(2, 2, 2)
        intTable.Rows.Add(3, 3, 3)

        stringTable.Columns.Add("ColA", GetType(String))
        stringTable.Columns.Add("ColB", GetType(String))
        stringTable.Columns.Add("ColC", GetType(String))

        stringTable.Rows.Add("A", "A", "A")
        stringTable.Rows.Add("B", "B", "B")
        stringTable.Rows.Add("C", "C", "C")

        DataGridView2.DataSource = intTable
        DataGridView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        DataGridView2.AllowUserToAddRows = False

        DataGridView1.DataSource = stringTable
        DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        DataGridView1.AllowUserToAddRows = False

        Dim indexColumn1 As New Data.DataColumn("Index", GetType(Integer))
        Dim indexColumn2 As New Data.DataColumn("Index", GetType(Integer))
        intTable.Columns.Add(indexColumn1)
        stringTable.Columns.Add(indexColumn2)
        For i As Integer = 0 To intTable.Rows.Count - 1
            intTable.Rows(i)("Index") = i
            stringTable.Rows(i)("Index") = i
        Next

        Dim resultTable = From i In intTable.AsEnumerable()
                          Join s In stringTable.AsEnumerable()
                          On s("Index") Equals i("Index")
                          Select {i("Col1"), i("Col2"), i("Col3"), s("ColA"), s("ColB"), s("ColC")}

        Dim dt As New DataTable()
        dt.Columns.AddRange({New DataColumn("Col1"), New DataColumn("Col2"), New DataColumn("Col3"),
                             New DataColumn("ColA"), New DataColumn("ColB"), New DataColumn("ColC")})
        For Each result In resultTable
            dt.LoadDataRow(result, True)
        Next

        DataGridView3.DataSource = dt
        DataGridView3.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
        DataGridView3.AllowUserToAddRows = False

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接