Linq将表分组为数据表

时间:2014-08-09 16:59:42

标签: .net linq .net-4.5

我编写了一个返回DataTable对象的函数。对于以下代码

Public Function GetArtikelsAbove50(ByVal limit As Integer) As DataTable
    Dim query = _Set.Ten_Most_Expensive_Products.AsEnumerable.Where(Function(x) x.UnitPrice > limit) _
    .GroupBy(Function(x) x.UnitPrice)
    Return query.CopyToDataTable
End Function

querySystem.Data.EnumerableRowCollection(Of SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow)对象。代码运行,一切都很好。但是如果我补充一下:

.GroupBy(Function(x) x.UnitPrice)

编译器会使返回对象(query.CopyToDataTable)变得不完整。查询现在是一个System.Collections.Generic.IEnumerable(Of System.Linq.IGrouping(Of Decimal, SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow))对象,因此CopyToDataTable不再是其成员。由于我需要.GroupBy函数(有些适用于.Sum))我正在寻找一种方法将其与.CopyToDataTable结合使用。这是可能的,如果是的话,我该如何实现呢?

我想,mybe返回一个DataView Objeckt(Return query.AsDataView)会起作用,但同样的错误。

提示: 在我的研究中,我发现在this问题中,用户提到函数.CopyToDataTable "已被限制为IEnumerable,并且不适用于IEnumerable(T)" 。我不太熟悉数据集,我不确定这是否有助于解决问题。只是想分享信息,也许它很有帮助。

1 个答案:

答案 0 :(得分:1)

问题是应用GroupBy会改变表达式的内容。您的可枚举现在是IEnumerable

 System.Linq.IGrouping(Of Decimal, SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow)

而不仅仅是

 SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow

CopyToDataTableIEnumerable(of DataRow)上的扩展功能,因此对于这种新的匿名类型无法使用。

至于做什么......好吧,要恢复功能,您需要将新类型转换为DataRowDataRow的子类。

例如,您可以在DataSet中创建一个包含所需行结构的新表格(在此示例中,我们将其称为NewTable),这将导致一个新的,强烈的 - 要生成的类型为NewTableRow的类。

然后,您可以编写.Select语句将System.Linq.IGrouping(Of Decimal, SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow)个对象转换为NewTableRow个对象。

结果的IEnumerable(Of SPTest.northwindDataSet.NewTableRow)实例将再次提供CopyToDataTable

ETA:一个例子。免责声明:这是用C#编写的,并自动翻译成VB,因此可能存在一些怪癖。但你应该明白这个想法。

' We need an instance of the the target table to access the NewRow method
Dim newTable As New NewTable 
Dim newRows = query.[Select](Function(g) ' We're using an anonymous method here, but you could make it a regular method.
  'A quirk of DataTable & DataRow: you can't just "new" up a DataRow.  You have to use the
  'NewRow or generated, strongly-typed NewXXXXRow method to get a new DataRow.
  Dim newRow = newTable.NewNewTableRow() 
  ' You can now set the properties on your new strongly-typed DataRow.
  newRow.UnitPrice = g.Key   
  newRow.Quantity = g.Sum(Function(d) d.Quantity)
  ' Don't forget to return the result!
  Return newRow
End Function)

或者,您可以使用AddNewTableRow方法创建AND将新行添加到目标表。你甚至不需要使用CopyToDataTable