如何在没有循环的情况下加载通用类

发布于 2024-09-10 19:10:04 字数 1037 浏览 3 评论 0原文

好的,这就是我现在拥有的东西,它工作得很好,只是有点慢:

Public Function GetList() As List(Of SalesOrder)
Try
    Dim list As New List(Of SalesOrder)

    Dim ds As DataSet

    ds = cls.GetSalesOrderList 'CLS is the data access class


    For i = 0 To ds.Tables(0).Rows.Count - 1

        Dim row As DataRow = ds.Tables(0).Rows(i)
        Dim kk As SalesOrder = New SalesOrder()


        kk.ID = Val(row.Item("id") & "")
        kk.SalesOrderNo = row.Item("salesorderid") & ""
        kk.SalesOrderDate = row.Item("OrderDate") & ""
        kk.CustomerId = Val(row.Item("customerid") & "")

        list.Add(kk)

    Next
    Return list

    Catch ex As Exception
        Throw ex
    End Try

End Function

现在,一旦我开始从表中检索超过 10000 条记录,循环就会花费很长时间将值加载到泛型类中。有什么办法可以摆脱循环吗?我可以对泛型类执行类似以下操作吗?

txtSearch.AutoCompleteCustomSource.AddRange(Array. ConvertAll(Of DataRow, String)(BusinessLogic.ToDataTable.ConvertTo(WorkOr derList).Select(), Function(row As DataRow) row("TradeContactName"))) 

ok this is the thing I have right now which is working quite well except its a bit slow:

Public Function GetList() As List(Of SalesOrder)
Try
    Dim list As New List(Of SalesOrder)

    Dim ds As DataSet

    ds = cls.GetSalesOrderList 'CLS is the data access class


    For i = 0 To ds.Tables(0).Rows.Count - 1

        Dim row As DataRow = ds.Tables(0).Rows(i)
        Dim kk As SalesOrder = New SalesOrder()


        kk.ID = Val(row.Item("id") & "")
        kk.SalesOrderNo = row.Item("salesorderid") & ""
        kk.SalesOrderDate = row.Item("OrderDate") & ""
        kk.CustomerId = Val(row.Item("customerid") & "")

        list.Add(kk)

    Next
    Return list

    Catch ex As Exception
        Throw ex
    End Try

End Function

Now once I start retrieving more than 10000 records from the table, the loop takes long time to load values into generic class. Is there any way that I can get rid of loop? Can I do something like the following with the generic class?

txtSearch.AutoCompleteCustomSource.AddRange(Array. ConvertAll(Of DataRow, String)(BusinessLogic.ToDataTable.ConvertTo(WorkOr derList).Select(), Function(row As DataRow) row("TradeContactName"))) 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

薄荷梦 2024-09-17 19:10:04

我本以为问题不在于循环,而在于数据量。您的循环方法似乎只处理每一位数据一次,因此不会出现任何大规模的效率崩溃(例如对每行或类似的事情循环一次数据集,然后再次循环)。您选择的任何方法最终都必须循环遍历您的所有数据。

他们的方法可能比你的方法稍微高效一些,但我认为它们不会那么高效。我会看看您是否可以进行一些重构来减少数据集(例如,将其限制在某个时期或类似的范围内),或者您是否可以在数据库中而不是在代码中对该列表进行任何搜索或聚合。例如,如果您只是要对该列表的值求和,那么您几乎肯定可以通过使用一个存储过程来更好地完成该操作,该存储过程将在数据库而不是在代码中进行求和。

我知道这并没有直接回答你的问题,但这主要是因为我不知道更有效的方法。我把这个问题看作是总体上的优化,而不是如何做这个特定的优化。 :)

I would have thought the problem isn't with doing a loop but with volumes of data. Your loop method seems to process each bit of data only once so there isn't any massive efficiency crash (such as looping over the dataset once and then again for each row or that kind of thing). Any method you choose is at the end of the day going to have to loop through all your data.

Their methods might be slightly more efficient than yours but they aren't going to be that much more so I'd think. I'd look at whether you can do some refactoring to reduce your data set (eg limit it to a certain period or similar) or whether you can do whatever searching or aggregating of that list you intend in the database instead of in code. eg if you're just going to sum the values of that list then you can almost certainly do it better by having a stored procedure that will do the summing on the database rather than in the code.

I know this hasn't directly answered your question but this is mainly because I don't know of a more efficient method. I took the question as asking for optimisation in general though rather than how to do this specific one. :)

谁把谁当真 2024-09-17 19:10:04

如果您仍然一次枚举每一行,则将循环转换为某种 LINQ 构造并不一定会提高性能。如果您不需要让消费者能够从列表中添加/删除(看起来可能是这种情况),您可以返回 IEnumerable(Of SalesOrder),然后在这种情况下您可以创建一个枚举器来处理这。这样,数据集会一次性加载,但只有在枚举项目时才会将其转换为对象,这可能会影响性能。

像这样的事情:

Return ds.Tables(0).Rows.Select(Function(dr As DataRow) Return New SalesOrder ... );

我的 VB 与 LINQ 有点生疏,但有这样的效果,其中 ... 是实例化新 SalesOrder 的代码。这只会在枚举 IEnumerable(Of SalesOrder) 时创建一个新的 SalesOrder 对象(懒惰的,如果你愿意的话)。

Converting the loop into some kind of LINQ construct isn't necessarily going to improve performance if you're still enumerating over every row at once. You could return IEnumerable(Of SalesOrder) if you don't need to give the consumer the ability to add/remove from the list (which it looks like might be the case), and then in that case you could create an enumerator to handle this. That way, the dataset is loaded all at once, but the items are only converted into objects when they're being enumerated over, which may be part of your performance hit.

Something like this:

Return ds.Tables(0).Rows.Select(Function(dr As DataRow) Return New SalesOrder ... );

My VB with LINQ is a little rusty, but something to that effect, where the ... is the code to instantiate a new SalesOrder. That will only create a new SalesOrder object as the IEnumerable(Of SalesOrder) is being enumerated over (lazy, if you will).

后eg是否自 2024-09-17 19:10:04

嘿保罗,你的意思是类似下面的代码,

Dim list As New List(Of SalesOrder) 

Dim kk As SalesOrder = New SalesOrder() 

Function DrToOrder(dr as datareader)     
        kk.ID = Val(dr.Item("id") & "") 
        kk.SalesOrderNo = dr.Item("salesorderid") & "" 
        list.Add(kk)     
End function 

Function LoadData()     
         datareader.Rows.Select(DrToOrder)     
End function 

你是在谈论类似上面的代码吗?

Hey Paul, You mean something like below code

Dim list As New List(Of SalesOrder) 

Dim kk As SalesOrder = New SalesOrder() 

Function DrToOrder(dr as datareader)     
        kk.ID = Val(dr.Item("id") & "") 
        kk.SalesOrderNo = dr.Item("salesorderid") & "" 
        list.Add(kk)     
End function 

Function LoadData()     
         datareader.Rows.Select(DrToOrder)     
End function 

Are you talking about something like above code?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文