2013-03-04 8 views
6

Ich habe eine Methode geschrieben, die Reflektion verwendet, um mehrere stark typisierte Datatables in einer .NET-Anwendung zu laden. Wenn ich wie unten laufen würde, funktioniert alles - auch keine geworfenen Ausnahmen. Aber wenn ich den kommentierten Teil stattdessen verwende (alles andere gleich haltend), dann bekomme ich Fehler beim Aktivieren der Einschränkungen Fehler hier beschrieben: enter link description here.DataTable load() Constraint-Fehler

Wenn ich mir anschaue, was in der Fehler-Array ist, ist es immer folgendes:

"Column 'AEDelegateName' does not allow DBNull.Value." 

und die ItemArray für einen Fehler wird in etwa so aussehen:

[0] = {} 
[1] = "Some Value" 

Das hat mich überrascht, da Ich würde nur 1 Spalte in einem Skript erwarten, das 1 Spalte und nicht 2 wie oben angegeben auswählt. Ich stelle mir auch vor, dass dies dem Problem nahekommt, da einer von ihnen scheinbar null ist.

Mein Skript gibt nicht null zurück, und ich kann es schnell und visuell bestätigen, sowie sagen Dinge wie NOT NULL in der Abfrage, die ich verwende.

private void GetData(string query, Component tableAdapter) 
{ 
    OracleCommand command = new OracleCommand(); 
    command.Connection = conn; 
    command.CommandText = query; 
    command.CommandType = CommandType.Text; 
    command.CommandTimeout = 3000; 
    OracleDataReader reader = command.ExecuteReader(CommandBehavior.SingleResult); 
    MethodInfo[] methods = tableAdapter.GetType().GetMethods(); 
    MethodInfo getDataMethod = tableAdapter.GetType().GetMethod("GetData"); 
    DataTable table = (DataTable)getDataMethod.Invoke(tableAdapter, null); 
    Type[] paramTypes = new Type[] { table.GetType() }; 
    MethodInfo updateMethod = tableAdapter.GetType().GetMethod("Update", paramTypes); 
    foreach (DataRow row in table.Rows) 
    { 
     row.Delete(); 
    } 
    //try 
    //{ 
    // if (reader.HasRows) 
    // { 
    //  table.Load(reader, LoadOption.OverwriteChanges, FillErrorHandler); 
    // } 
    //} 
    //catch (Exception e) 
    //{ 
    // DataRow[] errors = table.GetErrors(); 
    //} 
    while (reader.Read()) 
    { 
     try 
     { 
      List<object> newRow = new List<object>(); 
      for (int i = 0; i < reader.FieldCount; ++i) 
      { 
       object currentValue = reader.GetValue(i); 
       Debug.WriteLine("Value: "+currentValue); 
       newRow.Add(currentValue); 
      } 
      table.Rows.Add(newRow.ToArray()); 
     } 
     catch (ConstraintException e) 
     { 
      DataRow[] errors = table.GetErrors(); 
     } 
    }    
    updateMethod.Invoke(tableAdapter, new object[]{table}); 
    reader.Close(); 
} 
+0

Könnten Sie die Beziehung zwischen der 'DataTable-Tabelle' und der Abfrage, die OracleDataReader ausführt, beschreiben? Ich habe das Gefühl, dass das Schema für beide unterschiedlich ist und dass 'DataTable.Load()' die Definition überschreibt und somit die Beschränkung auslöst. – Caramiriel

+0

welcher 'catch' Block macht den Fang? – radarbob

+0

.... @Caramiriel könnte auf dem richtigen Weg sein, aber ich werde eine gebildete WAG nehmen und vorschlagen, 'AcceptChanges()' nach der Zeile zu löschen Schleife. – radarbob

Antwort

1

Per Dokumentation für DataTable.Load Method (IDataReader, LoadOption), vermute ich, dass Sie das Verhalten in dem Auszug unten beschrieben begegnen können. Haben Sie die Anzahl der von Ihrer Abfrage zurückgegebenen Spalten im Vergleich zur Anzahl der Spalten in Ihrer DataTable überprüft? Entspricht der Name der von der Abfrage zurückgegebenen Spalte dem gewünschten Spaltennamen in Ihrer DataTable?

Zustand: Die Schemata sind kompatibel, aber die geladenen Ergebnismenge Schema enthält weniger Spalten als die Datentabelle der Fall ist.

Behavior: Wenn eine fehlende Spalte einen Standardwert hat oder definiert den Datentyp der Spalte ist NULL festlegbaren, die Load-Methode ermöglicht die Zeilen sein hinzugefügt, die Standard oder Null-Wert für die fehlende Spalte ersetzt wird. Wenn kein Standardwert oder null verwendet werden kann, löst die Load-Methode eine Ausnahme aus. Wenn kein bestimmter Standardwert angegeben wurde, verwendet die Load -Methode den Nullwert als impliziten Standardwert.

Ihr Code in der While-Schleife funktioniert wahrscheinlich, weil es keinen Versuch unternimmt, Schema zu entsprechen. Sie füllt Werte nur positionsmäßig und ist erfolgreich, solange die Typen kompatibel sind, keine Einschränkungen verletzt werden und das Array nicht mehr Elemente enthält als die Zeile Spalten hat.