2009-03-11 5 views
8

Hey Leute, also bin ich auf etwas gestoßen, das vielleicht ein Fehler in der Extension-Methode .CopyToDataTable ist.Wie man mit einem Fehler in System.Data.DataTableExtensions.CopyToDataTable() umgehen kann

Diese Methode wird verwendet, indem (in VB.NET) System.Data.DataTableExtensions importiert und dann die Methode für ein IEnumerable aufgerufen wird. Sie würden dies tun, wenn Sie eine Datentabelle mit LINQ filtern und dann die DataTable am Ende wiederherstellen möchten.

heißt:

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 dem obigen Beispiel die "WHERE" Filterung möglicherweise keine Ergebnisse zurück. Wenn dies geschieht, löst CopyToDataTable eine Ausnahme aus, da keine DataRows vorhanden sind.

Warum?

Das sollte ein korrektes Verhalten eine Datatable mit Rows.Count zurückkehren = 0.

jemand eine saubere Abhilfe dazu in einer solchen Art und Weise denken, dass sich bewusst, wer CopyToDataTable ruft muss nicht sein dieses Problem?

System.Data.DataTableExtensions ist eine statische Klasse, so kann ich das Verhalten nicht überschreiben .... irgendwelche Ideen? Habe ich etwas verpasst?

prost

UPDATE:

ich dies als ein Problem zu Connect eingereicht haben. Ich würde noch einige Vorschläge mögen, aber wenn Sie mir zustimmen, könnten Sie das Problem bei Verbindung über den Link oben

prost

Antwort

2

Bis Microsoft beheben dieses Problem vote up, ist hier eine Arbeit um:

Erstellen Sie Ihre eigene Extension-Methode, die die CopyToDataTable-Methode verwendet, wenn DataRows vorhanden sind. Wenn nicht, wird eine leere DataTable zurückgegeben.

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); 
      } 
     } 
    } 
+1

Ich denke, dass dies etwas verbessert werden könnte, um '! Source.Any()' anstelle von 'Source.Count() == 0' zu verwenden. 'Any' hört auf, sobald Ergebnisse gefunden werden. – row1

+0

Viel mehr als leicht –

+2

Dies ist kein Fehler; Das Verhalten ist sehr bewusst und bewusst.Eines der ersten Dinge, die 'CopyToDataTable' tut, ist eine Zeile zu suchen, die zugrunde liegende Tabelle zu finden und die Spalten in Ihre neue' DataTable' zu ​​kopieren. Ihre Problemumgehung erstellt eine leere 'DataTable' ohne Spalten. Sie können damit in einer DataSource durchkommen (es wird nicht auf die Tabelle schauen, wenn es keine Zeilen hat), aber in anderen Szenarien können Sie nicht. – Brian

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

.AsDataView().ToTable() gibt eine leere Tabelle mit derselben Struktur wie someDataTable wenn es jetzt zurückgegebenen Zeilen von .Where()

+0

cool, ich werde es ausprobieren, cheers vince – andy

+0

ein Problem, das ich mit Ihrer benutzerdefinierten Erweiterung sehe, ist der Scheck für .Count. Wenn ich mich nicht irre, erzwingt .Count das Lesen der gesamten Enumeration. Wenn Ihre Zahl 1000 lautet, lesen Sie daher die gesamte Enumeration und rufen CopyToDataTable() auf, wodurch wahrscheinlich ein weiterer Lesevorgang erzwungen wird. Haben Sie darüber nachgedacht, ob .GetEnumerator(). MoveNext() == true? Wenn dies der Fall ist, hat die Aufzählung mindestens eine Zeile, und das ist alles, worum Sie sich Sorgen machen, nicht die Anzahl. – Vince

+0

guter Punkt Vince, du hast völlig Recht. Ich werde es aktualisieren, Prost! – andy

1

ich auf dieses Problem kam heute und arbeiteten einen workaround, wenn es hilft.

Entschuldigung, aber das Blog ist in C#, aber ich habe nur ein IEnumerable auf der LINQ-Variable verwendet und überprüfen .Current, um zu sehen, ob es Zeilen zurückgegeben hat.

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 
} 
Verwandte Themen