How to deal with a flaw in System.Data.DataTableExtensions.CopyToDataTable()

感情迁移 提交于 2019-12-01 15:57:51

问题


Hey guys, so I've come across something which is perhaps a flaw in the Extension method .CopyToDataTable.

This method is used by Importing (in VB.NET) System.Data.DataTableExtensions and then calling the method against an IEnumerable. You would do this if you want to filter a Datatable using LINQ, and then restore the DataTable at the end.

i.e:

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

In the example above, the "WHERE" filtering might return no results. If this happens CopyToDataTable throws an exception because there are no DataRows.

Why?

The correct behavior should be to return a DataTable with Rows.Count = 0.

Can anyone think of a clean workaround to this, in such a way that whoever calls CopyToDataTable doesn't have to be aware of this issue?

System.Data.DataTableExtensions is a Static Class so I can't override the behavior....any ideas? Have I missed something?

cheers

UPDATE:

I have submitted this as an issue to Connect. I would still like some suggestions, but if you agree with me, you could vote up the issue at Connect via the link above

cheers


回答1:


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

.AsDataView().ToTable() returns an empty table with the same structure as someDataTable if there are now rows returned from .Where()




回答2:


Until Microsoft fix this issue, here's a work around:

Create your own Extension method which uses the CopyToDataTable method if there are DataRows, if there aren't, then it returns an empty 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);
            }
        }
    }



回答3:


I came across this problem today and worked out a workaround if it helps.

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.




回答4:


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
}


来源:https://stackoverflow.com/questions/636765/how-to-deal-with-a-flaw-in-system-data-datatableextensions-copytodatatable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!