2016-06-08 14 views
0

Der folgende Code funktioniert genau so, wie er beim ersten Mal auf meiner DataTable ausgeführt wird. Die Datentabelle wird geladen und aktualisiert alle Spaltendaten, die mit der angegebenen Zeichenfolge angegeben wurden. Alles ist ordnungsgemäß geschlossen (und vermutlich gelöscht).DataTable ArgumentOutOfRangeException

public void AppendKeyColumn(string appendText, params string[] columnNames) 
{    
    string columns = ""; 

    // Create a list of the columns to use, comma separated. 
    for (int column = 0; column < columnNames.Length; column++) 
    { 
     if ((column + 1) == columnNames.Length) 
     { 
      columns += columnNames.ElementAt(column); 
     } 
     else 
     { 
      columns += columnNames.ElementAt(column) + ", "; 
     } 
    } 

    // SQL Statement for querying the file. Change after FROM for proper table name. 
    string sql = "SELECT " + columns + " FROM " + TableName; 

    // Using to create a command variable (so it will be properly disposed after block execution). 
    using (OleDbCommand cmd = new OleDbCommand(sql, Connection)) 
    { 
     // Open a connection to the data source. 
     Connection.Open(); 

     // Open the datareader, load the datatable with the data in the reader, and then close the reader. 
     Data = cmd.ExecuteReader(); 
     Table.Load(Data); 
     Data.Close(); 

     foreach (string column in columnNames) 
     { 
      // Run UPDATE statement to append text to end of column name. 
      for (int row = 0; row < Table.Rows.Count; row++) 
      { 
       string sql2 = "UPDATE " + TableName + " SET " + column + " = @newName WHERE " + 
         column + " = @oldName"; 

       using (OleDbCommand cmd2 = new OleDbCommand(sql2, Connection)) 
       { 
        string oldString = Table.Rows[row][0].ToString();       
        string newString = oldString.Remove(oldString.Length - 1); 
        newString = newString.Insert(newString.Length, appendText); 

        cmd2.Parameters.AddWithValue("@newName", newString); 
        cmd2.Parameters.AddWithValue("@oldName", oldString); 

        if (!Equals(oldString.Substring(oldString.Length-1, 1), appendText)) 
        { 
         cmd2.ExecuteNonQuery(); 
        } 
       } 
      } 
     } 

     Table.Clear(); 
     Connection.Close(); 
    } 
} 

Meine Probleme liegen bei, wenn ich diesen Code zum zweiten Mal ausführen. Wenn ich es nochmal an der gleichen Tabelle anrufe, bekomme ich folgenden Fehler (ab dieser Zeile string newString = oldString.Remove(oldString.Length - 1);). Die DataTable sollte keine leeren Zeichenfolgen in den Spalten enthalten, für die dies aufgerufen wird. Beim ersten Aufruf wird die DataTable geladen und das funktioniert wie erwartet. Beim zweiten Durchlauf scheint es die korrekte Anzahl von Zeilen in der DataTable zu bestätigen, es scheint jedoch physisch leer zu sein.

InnerException: 
System.ArgumentOutOfRangeException: StartIndex cannot be less than zero. 
Parameter name: startIndex 
    at System.String.Remove(Int32 startIndex) 

Ich gehe davon aus, dass ich wahrscheinlich etwas Grundlegendes übersehe, aber könnte jemand bitte meine in die richtige Richtung zeigen?

+0

wie einer des Spaltenwertes Sieht null ist, so dass es oldstring.length als 0 hat daher ist es diesen Fehler zu werfen? – Akhilesh

Antwort

1

Ihr Problem Nähte durch das Table-Objekt verursacht werden, die ich nehme an, es ein Datatable ist, also wenn Sie Table = new DataTable; vor dem hinzufügen Linie Table.Load(Data);

Und hier ist es eine Möglichkeit, in der Tabelle eine gute Bereinigung zu machen
string sql = String.Format("SELECT ({0}) FROM {1};", String.Join(", ", columnNames), TableName);

+0

Das hat es behoben! Warum genau muss ich ein neues DataTable instanziieren, bevor es es wiederverwenden kann? Ich war unter der Annahme, ich könnte es einmal in meinem Objekt erstellen und dann einfach Clear() und Load() es wieder ... –

+1

DataTable ist eine temperamentvolle Komponente, wenn es um Garbage Collection geht. Was passiert, ist, dass die DataTable glaubt, dass sie schon geladen ist, so dass sie nicht das zweite Mal geladen wird. –

0

Sie laufen in leere Zeichenfolgen. Ohne sich zu in-Tiefe, eine Sache, die Sie tun können, um dies zu beheben ist:

var newString = ""; 
if(oldString != String.Empty) 
{ 
    newString = oldString.Remove(oldString.Length - 1); 
} 
+0

Entschuldigung. Ich werde meinen Beitrag bearbeiten, um zu klären, aber es gibt keine leeren Zeichenfolgen in den Spalten, für die ich diese Funktion verwende. Es sollte keine leeren Strings geben. Beim ersten Lauf gibt es tatsächlich Datensätze in der DataTable. Beim zweiten Durchlauf wird die richtige Anzahl von Zeilen angezeigt ... aber es scheint nicht wirklich die Werte zu laden? –