8

我遇到了一些可能是 Extension 方法中的缺陷.CopyToDataTable

此方法由 Importing(在 VB.NET 中)使用System.Data.DataTableExtensions,然后针对 IEnumerable 调用该方法。如果您想使用 LINQ 过滤数据表,然后在最后恢复数据表,您可以这样做。

IE:

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”过滤可能不返回任何结果。如果发生这种情况,CopyToDataTable 会抛出异常,因为没有 DataRows。

为什么?

正确的行为应该是返回 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 方法,如果没有,则返回一个空的 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

我今天遇到了这个问题,如果有帮助,我想出了一个解决方法。

Sorry, but the blog is in C#, but I just used an IEnumerable on the LINQ variable and check .Current to see if it had returned any rows.

于 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 回答