【问题标题】:Group by a column then Add each group to datatable then into a dataset按列分组,然后将每个组添加到数据表,然后添加到数据集中
【发布时间】:2012-10-05 18:40:10
【问题描述】:

这样的事情最好的方法是什么?

这是我的数据表

╔═══════════════╦═══════════════╦═══════════════╗
║ Product Name  ║ Product Price ║ Product Group ║
╠═══════════════╬═══════════════╬═══════════════╣
║ Skirt Red     ║            99 ║             1 ║
║ Jeans Blue    ║            49 ║             2 ║
║ Jeans Black   ║            49 ║             2 ║
║ Skirt Blue    ║            99 ║             1 ║
║ T-shirt White ║            20 ║             3 ║
║ T-shirt Green ║            20 ║             3 ║
║ Jeans Grey    ║            49 ║             2 ║
╚═══════════════╩═══════════════╩═══════════════╝

我将使用 LINQ 按产品组列对该数据表进行分组,以生成以下组

Group #1
    ╔═══════════════╦═══════════════╦
    ║ Product Name  ║ Product Price ║ 
    ╠═══════════════╬═══════════════╬
    ║ Skirt Red     ║            99 ║             
    ║ Skirt Blue    ║            99 ║             
    ╚═══════════════╩═══════════════╩

Group #2
        ╔═══════════════╦═══════════════╦
        ║ Product Name  ║ Product Price ║ 
        ╠═══════════════╬═══════════════╬
        ║ Jeans Blue    ║            49 ║             
        ║ Jeans Black   ║            49 ║ 
        ║ Jeans Grey    ║            49 ║
        ╚═══════════════╩═══════════════╩
Group #3
        ╔═══════════════╦═══════════════╦
        ║ Product Name  ║ Product Price ║ 
        ╠═══════════════╬═══════════════╬
        ║ T-Shirt White ║            20 ║             
        ║ T-Shirt Green ║            20 ║ 
        ╚═══════════════╩═══════════════╩

现在问题是

  1. 如何使用 LINQ 按产品组列进行分组(完成)
  2. 如何从结果组中删除产品组列?
  3. 如何将每个组添加到单独的数据表中,然后添加所有 表到单个数据集?(完成)
  4. 假设有我不想在结果中显示的列 群里,怎么隐藏?

这是我迄今为止尝试过的

    Dim ds As New DataSet
    Dim query = From r In bookedorders Group By key = r.Field(Of Integer)("productgroup") Into Group
    For Each grp In query
        Dim x As New DataTable
        x = grp.Group.CopyToDataTable()
        ds.Tables.Add(x)
    Next

除了我不确定如何选择特定列之外,现在这正在工作,就像我不想显示结果数据表中的所有列

【问题讨论】:

  • @channs 刚刚将其添加到问题中

标签: vb.net linq datatable group-by dataset


【解决方案1】:

1.如何使用 LINQ 按产品组列进行分组

听起来您所要求的在 LINQ 中在技术上并不称为组。 linq 中的分组意味着您从一列中获取值并以某种方式组合它们(SUM、Average)并为每个唯一标识符显示一条记录。在您的示例中,如果您想显示每组的平均价格,那么这将需要一个组,但从您的解释看来,您只需要 3 个不同的选择语句,如下所示:

From r in products where r.groupID = YourControlVariable select r.ProductName, r.ProductPrice

YourControlVariable 将是每个组 ID。此 LINQ 将为您提供您概述的三个表,然后您可以从那里调用 CopyToDataTable 函数来处理 LINQ 返回的内容,并设置一个与该函数的输出相等的临时数据表。

2.如何从结果组中删除产品组列?

请参阅第 1 点的 linq,通过仅列出您要选择的列,您实际上将忽略任何未列出的列。

3.如何将每个组添加到单独的数据表中,然后将所有表添加到单个数据集中?

如果您知道您将使用的 groupID,这将相当简单地在循环中完成。您可以在循环内创建一个临时数据表并将其设置为包含第 1 点的 linq 结果。一旦获得结果,您就可以命名该表并将其添加到数据集中,一旦循环完成,您的临时数据表将是消失了,但您可以在数据集中按名称引用它们。

4.假设有我不想在结果组中显示的列,我该如何隐藏它们?

参考第 1/2 点。

编辑:

正如您所描述的问题,我认为在 LINQ 中使用 group by 会使其变得不必要地复杂,因为如果您想提取单个属性,则必须处理匿名类型。这是一个简短的 sn-p,它获取所有不同的组 id,然后使用 LINQ 提取每种类型的所有产品,将它们添加到表中,然后将命名表添加到数据集中。您可以删除名称部分或将其更改为您想要的任何内容,这并不重要。

Dim ds As New DataSet
Dim groupIDs = From r in bookedorders Select r.Item("productgroup") Distinct
for each r in groupIDs
    Dim query = From t in bookedorders Where t.Item("productgroup") = r select t.Item("ProductName"), t.Item("ProductPrice")
    If query IsNot Nothing AndAlso query.Any Then
        Dim tempDT as new DataTable
        tempDT.Merge(query.CopyToDataTable)
        tempDt.Name = "ProductID" & r
        ds.Tables.Add(tempDT)
    End IF
Next

我已经稍微更改了您的示例以使用 Item 集合,但这仅在 bookedorders 是数据表时才有效。

编辑#2:

想了想,上面的例子还是会给你一个匿名类型的集合。所以为了解决这个问题,你可以改变

Dim query = From t in bookedorders Where t.Item("productgroup") = r select t.Item("ProductName"), t.Item("ProductPrice")

线条看起来像:

Dim query = From t in bookedorders Where t.Item("productgroup") = r select t

然后在您的 if 语句中将如下所示:

Dim tempDT as new DataTable
tempDT.Merge(query.CopyToDataTable)
tempDT.Columns.Remove("GroupID")
tempDt.Name = "ProductID" & r
ds.Tables.Add(tempDT)

同样,这仅在您通过数据表进行 LINQing 并获得 Enumerable(Of DataRow) 作为结果时才有效,这是更可取的。

【讨论】:

  • 你好,请参考我尝试过的代码,但我不确定如何选择特定列
  • 我添加了一些代码示例,我认为这些代码可以完成您正在寻找的内容,与黄蜂的答案相比,这是一种相当全面的方法,但这不需要使用匿名类型,以便您可以使用CopyToDataTable 方法。
  • 添加了另一个编辑,因为我意识到我避免匿名类型的工作不会像以前那样工作。
  • @yes 但我通过创建另一个表来解决这个问题,该表只包含我想要的列然后使用它,谢谢
【解决方案2】:

我不习惯 VB.NET 语法,应该是这样的(我不保证 100% 代码实际编译):

Dim query = From r In bookedorders _
            Group By key = r.Field(Of Integer)("productgroup") Into Group _
            Select New With { _
              .key, _
              .Rows = From o In Group _
                      Select New With { _
                          .Name = r.Field(Of String)("productname") } }

如需进一步检查,您可以查看:

http://msdn.microsoft.com/en-us/vstudio/bb737908

尤其是 GroupBy - Nested 示例,您可以在其中查看如何在组内进行投影。

如果你解决它并在我的回答中发现一些编译错误,请告诉我什么,我会修复它。

【讨论】:

  • 是的,但问题是我不能使用copytodatatable
猜你喜欢
  • 2019-01-20
  • 2013-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
相关资源
最近更新 更多