【问题标题】:Improve Linq to Datatable Performance提高 Linq 到数据表的性能
【发布时间】:2015-11-15 14:55:51
【问题描述】:

我有一个包含 500K 行的数据表,格式如下;

Int | Decimal | String

我们使用的是单例模式,最终我们的DataTable 需要以List(Of AssetAllocation) 结尾,其中AssetAllocation 是:

Public Class AssetAllocation
    Property TpId() As Integer
    Property Allocation As List(Of Sector)
End Class

Public Class Sector
    Property Description() As String
    Property Weighting As Decimal
End Class

我正在使用的 linq;

Private Shared Function LoadAll() As List(Of AssetAllocation)

        Dim rtn = New List(Of AssetAllocation)

        Using dt = GetRawData()

            Dim dist = (From x In dt.AsEnumerable Select x!TP_ID).ToList().Distinct()

            rtn.AddRange(From i As Integer In dist
                         Select New AssetAllocation With {
                            .TpId = i,
                            .Allocation = (From b In dt.AsEnumerable
                                           Where b!TP_ID = i Select New Sector With {
                                               .Description = b!DESCRIPTION.ToString(),
                                               .Weighting = b!WEIGHT
                                           }).ToList()})
        End Using

        Return rtn
    End Function

执行 linq 需要很长时间,这是由于内部查询构造了扇区列表。不同的列表包含 80k

这可以改善吗?

【问题讨论】:

    标签: c# vb.net linq datatable linq-to-dataset


    【解决方案1】:

    如果我了解您要执行的操作,则此查询应该具有更好的性能。诀窍是使用GroupBy 以避免在每次迭代中搜索整个表以查找匹配的id。 我已经用 C# 编写了它,但我相信你可以将它翻译成 VB。

    var rtn  = 
            dt.AsEnumerable()
            .GroupBy(x => x.Field<int>("TP_ID"))
            .Select(x => new AssetAllocation()
            { 
                TpId = x.Key, 
                Allocation = x.Select(y => new Sector
                {
                    Description =  y.Field<string>("Description"),
                    Weighting = y.Field<decimal>("WEIGHT") 
                }).ToList()
            }).ToList();
    

    【讨论】:

    • 效果很好。就像我理解的那样,通过不必为每次迭代循环遍历整个数据表来帮助分组?
    • @Dooie GroupBy 构建一个内部哈希表,其中 TpId 是键,数据行是值。 HashTables 具有 O(1) 查找,因此可以非常快速地确定一行属于哪个 TpId。
    猜你喜欢
    • 2014-11-21
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    相关资源
    最近更新 更多