Linq将分组表返回为数据表
Posted
技术标签:
【中文标题】Linq将分组表返回为数据表【英文标题】:Linq Return grouped Table as Datatable 【发布时间】:2014-10-02 23:08:03 【问题描述】:我编写了一个返回 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
query
是一个 System.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(of T)”。我对数据集不太熟悉,我不确定这是否有助于解决问题。只是想分享一下信息,也许有帮助。
【问题讨论】:
【参考方案1】:问题是应用GroupBy
会改变你的表达方式。您的枚举现在是
System.Linq.IGrouping(Of Decimal, SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow)
而不仅仅是
SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow
CopyToDataTable
是IEnumerable(of DataRow)
的扩展函数,因此不适用于这种新的匿名类型。
至于要做什么...好吧,要恢复函数,您需要将新类型转换为DataRow
或DataRow
的子类。
例如,您可以在DataSet
中创建一个具有所需行结构的新表(在本例中我们称之为NewTable
),这将导致一个名为NewTableRow
的新强类型类成为生成。
然后您可以编写.Select
语句将System.Linq.IGrouping(Of Decimal, SPTest.northwindDataSet.Ten_Most_Expensive_ProductsRow)
对象转换为NewTableRow
对象。
所产生的IEnumerable(Of SPTest.northwindDataSet.NewTableRow)
实例将使CopyToDataTable
再次可用。
预计到达时间:一个例子。免责声明:这是用 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
方法创建新行并将其添加到目标表。你甚至不需要使用CopyToDataTable
!
【讨论】:
你好安,谢谢你的回答。关于上一节之前的部分:您能否给我更多关于如何使用 .Select 语句将我的对象转换为 NewTableRow 对象的信息? 太棒了!非常感谢您的回答!以上是关于Linq将分组表返回为数据表的主要内容,如果未能解决你的问题,请参考以下文章
Linq to SQL -- Group ByHaving和ExistsInAnyAllContains