1

处理这种事情的最佳方法是什么?

所以这是我的数据表

╔═══════════════╦═══════════════╦═══════════════╗
║ 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

现在这是可行的,除了我不确定如何选择特定列,就像我不想显示结果数据表中的所有列

4

2 回答 2

1

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

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

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

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

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

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

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

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

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

请参阅第 1/2 点。

编辑:

正如您所描述的问题,我认为在 LINQ 中使用 group by 会使其变得不必要地复杂,因为如果您想提取单个属性,则必须处理匿名类型。这是一个简短的片段,它获取所有不同的组 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)结果时才有效,这是可取的。

于 2012-10-15T18:27:08.493 回答
0

我不习惯 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 - 嵌套示例,您可以在其中查看如何在组内进行投影。

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

于 2012-10-15T20:26:56.720 回答