2

リストの種類に関する問題を解決しようとしています。まず、DBにストアドプロシージャがあり、単一の列を選択して、VBのアプリで続行しようとしています。メソッド関数を作成することにより、(CloseConnection動作を使用して)SqlCommandを介してロードするDataTableを宣言しました。その後、途中のストアドプロシージャからの行/アイテムを入力する必要がある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 eachループで反復することですが、特にリストに1つの列から数千行が含まれる場合は、パフォーマンスを最大限に活用するためにこれを望んでいません。したがって、基本的には、For / For Eachループを使用せずに、それらの項目をそのDataTableからList(Of String)に挿入します。

Visual Studio 2010 Ultimate、.NETFramework4.0で実行されます。

4

2 に答える 2

3

あなたはまったく必要ありません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 から要素を直接読み取るのと同じように、より便利な方法で行うことができます。


もう 1 つのアドバイス: パフォーマンスを測定するまでは、パフォーマンスについて推論しようとするべきではありません。たとえば、行collection = dt.AsEnumerable.ToListはおそらく既に DataTable 全体をループしており、各 DataRow 参照を DataRows のリストにコピーしています。したがって、この行では、回避しようとしているパフォーマンスの低下が既に発生しています。

Forそのため、一部のループが常に一部のステートメントよりも遅いと自動的に想定しないでください。測定してから最適化します。

于 2012-05-22T10:05:28.093 に答える
1

列が 1 つしかないと仮定すると、それをキャストDataRowするように指示するだけで済みます。ConvertAll

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

c#-2-vb の翻訳を提供してくれたBinary Worrierに感謝します。

于 2012-05-22T10:01:24.667 に答える