VB : 是否可以从列表(数据行)转换为列表(字符串)



我正在尝试解决有关列表类型的问题。首先,我的数据库中有一个存储过程,它选择单个列,我尝试在 VB 中的应用程序中继续它。通过创建一个方法函数,我声明了一个通过 SqlCommand 加载的 DataTable(具有 CloseConnection 行为(。之后,我公开声明了一个 List(Of String(,它需要使用正在进行的存储过程中的行/项进行填充。下面是我的代码片段:

Dim dt As New DataTable()
        Try
            If conn.State = ConnectionState.Open Then
                conn.Close()
            Else
                conn.Open()
                Dim cmd = New SqlCommand("LoadCodes", conn)
                cmd.CommandType = CommandType.StoredProcedure
                dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection))
                Dim collection As New List(Of DataRow)
                collection = dt.AsEnumerable.ToList
                LPrefix = collection.Cast(Of String)()
            End If
        Catch ex As Exception
            MsgBox(ex.Message + vbCritical)
        End Try

LPrefix = collection.Cast(Of String)()我收到异常错误的地方,告诉我我无法真正转换它。旧时尚的方式是迭代 for/for 每个循环,但这不是我想要的最佳性能利用,特别是如果列表在一列中有数千行。所以基本上我想将这些项目从该数据表插入到列表(字符串(而不使用 For/For 每个循环。

运行在Visual Studio 2010 Ultimate,.NET Framework 4.0上。

你根本不需要你的collection。使用 LINQ,可以直接从数据表中提取第一列:

dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection))  
LPrefix = (From row In dt.AsEnumerable()
           Select row.Field(Of String)(0)).ToList()

当然,这可能会在内部使用循环,但由于您希望将每个值复制到字符串列表中,因此如果不循环访问数据行,则无法执行此操作。


另一种选择是使用 IEnumerable(Of String) 而不是 List(Of String)

dt.Load(cmd.ExecuteReader(CommandBehavior.CloseConnection))  
Dim LPrefixNew As IEnumerable(Of String) = _
    From row In dt.AsEnumerable()
    Select row.Field(Of String)(0)

您可以像遍历列表一样遍历 IEnumerable,但求值是惰性的:只要您不访问元素,就不会遍历 DataTable。因此,访问此 IEnumerable 就像直接从 DataTable 读取元素一样,只是以更方便的方式。


另一个建议:在你衡量性能之前,你不应该试图推理它。例如,您的行collection = dt.AsEnumerable.ToList可能已经遍历了整个数据表,并将每个数据行引用复制到数据行列表中;因此,使用此行,您已经有了试图避免的性能损失。

因此,不要自动假设某些For循环总是比某些单个语句慢。测量它,然后优化。

假设你的DataRow只有一列,你只需要指示ConvertAll投射它:

LPrefix = collection.ConvertAll(Function(x) x[0].ToString)

感谢 Binary Worrier 的 c#-2-vb 翻译!

最新更新