8

おそらく Extension メソッドの欠陥である何かに遭遇しました.CopyToDataTable

このメソッドは、(VB.NET で) インポートSystem.Data.DataTableExtensionsしてから、IEnumerable に対してメソッドを呼び出すことによって使用されます。LINQ を使用して Datatable をフィルター処理し、最後に DataTable を復元する場合は、これを行います。

すなわち:

Imports System.Data.DataRowExtensions
    Imports System.Data.DataTableExtensions

    Public Class SomeClass
            Private Shared Function GetData() As DataTable
                Dim Data As DataTable

                Data = LegacyADO.NETDBCall


                Data = Data.AsEnumerable.Where(Function(dr) dr.Field(Of Integer)("SomeField") = 5).CopyToDataTable()


                Return Data

            End Function
    End Class

上記の例では、「WHERE」フィルタリングは結果を返さない可能性があります。これが発生した場合、DataRows がないため、CopyToDataTable は例外をスローします。

なんで?

正しい動作は、Rows.Count = 0 の DataTable を返すことです。

CopyToDataTable を呼び出す人がこの問題を意識する必要がないように、これに対する明確な回避策を考えられる人はいますか?

System.Data.DataTableExtensions は静的クラスであるため、動作をオーバーライドできません。何か案は?私は何かを逃しましたか?

アップデート:

これを問題としてConnectに提出しました。引き続きいくつかの提案をお願いしますが、私に同意する場合は、上記のリンクから Connect で問題に投票してください。

乾杯

4

4 に答える 4

12
someDataTable.AsEnumerable().Where(r => r.Field<string>("SomeField") == "SomeValue").AsDataView().ToTable();

.AsDataView().ToTable()someDataTableから行が返されたかのように、同じ構造を持つ空のテーブルを返します.Where()

于 2010-03-11T17:40:02.623 に答える
2

Microsoft がこの問題を修正するまで、次の回避策があります。

DataRows がある場合は CopyToDataTable メソッドを使用する独自の Extension メソッドを作成し、ない場合は空の DataTable を返します。

VB.NET

    Imports System.Data

Namespace CustomExtensions
    Public Module DataRowExtensionsOverride

        <System.Runtime.CompilerServices.Extension()> _
        Public Function CopyToDataTableOverride(Of T As DataRow)(ByVal Source As EnumerableRowCollection(Of T)) As DataTable

            If Source.Count = 0 Then
                Return New DataTable
            Else
                Return DataTableExtensions.CopyToDataTable(Of DataRow)(Source)
            End If

        End Function

    End Module
End Namespace

C#;

public static class DataRowExtensionsOverride
    {

        public static DataTable CopyToDataTableOverride<T>(this IEnumerable<T> Source) where T : DataRow {

            if (Source.Count() == 0) {
                return new DataTable();
            } else {
                return DataTableExtensions.CopyToDataTable<T>(Source);
            }
        }
    }
于 2009-03-17T04:12:20.020 に答える
1

今日この問題に遭遇し、それが役立つ場合は回避策を見つけました。

申し訳ありませんが、ブログは C# で書かれていますが、LINQ 変数で IEnumerable を使用し、.Current をチェックして行が返されたかどうかを確認しました。

于 2010-06-21T22:32:38.750 に答える
0
DataTable SearchDT = (DataTable)ViewState["SearchDT"];
DataTable NewDT = SearchDT.Select("BSerialNo='" + SerialNo + "' and BBranch='" + Branch + "' and Warehouse='" + WareHouse + "' and Buffer_ModelNo='" + PartNo + "'").CopyToDataTable();
//  first get an array of DataRows '
if ((NewDT.Rows.Count > 0))
{
    //first check to see if the array has rows
    DataTable dt = NewDT;
    PopUpGrdView.DataSource = dt;
    PopUpGrdView.DataBind();
    //dt now exists and contains rows
}
于 2017-01-11T05:01:12.557 に答える