2008-09-26 4 views
31

Wie kann ich herausfinden, welche Spalte und welcher Wert die Einschränkung verletzt? Die Ausnahmemeldung ist überhaupt nicht hilfreich:Was löst ConstraintException beim Laden von DataSet aus?

Fehler beim Aktivieren von Einschränkungen. Ein oder Weitere Zeilen enthalten Werte, die Nicht-Null-, Unique- oder Fremdschlüssel Constraints verletzen.

+2

Ich würde Ihnen mehr up-Stimmen, wenn ich könnte. Das ist mir auch ein Dorn im Auge. –

Antwort

20

Wie viele Leute, ich habe meine eigenen Standard-Datenzugriffskomponenten, die Verfahren umfassen einen Datensatz zurückzukehren. Wenn eine ConstraintException ausgelöst wird, wird das DataSet natürlich nicht an den Aufrufer zurückgegeben, sodass der Aufrufer nicht nach Zeilenfehlern suchen kann.

Was ich getan habe, ist zu fangen und rethrow ConstraintException in solchen Verfahren Reihe Fehlerdetails Anmeldung, wie im folgenden Beispiel (die Log4Net für die Protokollierung verwendet):

... 
try 
{ 
    adapter.Fill(dataTable); // or dataSet 
} 
catch (ConstraintException) 
{ 
    LogErrors(dataTable); 
    throw; 
} 
... 

private static void LogErrors(DataSet dataSet) 
{ 
    foreach (DataTable dataTable in dataSet.Tables) 
    { 
     LogErrors(dataTable); 
    } 
} 

private static void LogErrors(DataTable dataTable) 
{ 
    if (!dataTable.HasErrors) return; 
    StringBuilder sb = new StringBuilder(); 
    sb.AppendFormat(
     CultureInfo.CurrentCulture, 
     "ConstraintException while filling {0}", 
     dataTable.TableName); 
    DataRow[] errorRows = dataTable.GetErrors(); 
    for (int i = 0; (i < MAX_ERRORS_TO_LOG) && (i < errorRows.Length); i++) 
    { 
     sb.AppendLine(); 
     sb.Append(errorRows[i].RowError); 
    } 
    _logger.Error(sb.ToString()); 
} 
+0

Ihre LogErrors-Methode ist großartig! Hat mich heute buchstäblich gerettet. – Dave

1

ich einige Code hinzugefügt, die ich Es wurde festgestellt, dass es beim Debuggen von ConstraintException-Ereignissen nützlich ist. here

Hoffe, das hilft.

3

Wenn Sie eine starke typisierte Datasets verwenden und verwendet, um den visuellen Designer (XSD): tbl.Rows Zugriff auf [0] .RowError Informationen, müssen Sie die Füllen Methode erstellen.

Sie können die Get Methode nicht verwenden, da die DataTable in generierten Code instanziiert wird.

+0

wie du gesagt hast, brauchst du eine Füllung. Sehr eigenartig; warum würde ich eine fill-aussage benötigen, wenn ich nur einige daten bekomme (basic select). Irgendwo im Inneren dachte man, dass diese Fill-Methode von .net verwendet wird. Nachdem ich eine Fill-Methode generiert habe (keine Änderung am get), funktionierte es. – Obelix

1

Für Googler, die einen Ausschnitt möchten mehr Details über die ConstraintException zu erhalten:

try 
{ 
    ds.EnforceConstraints = true; 
} 
catch (ConstraintException ex) 
{ 
    string details = string.Join("", 
     ds.Tables.Cast<DataTable>() 
      .Where(t => t.HasErrors) 
      .SelectMany(t => t.GetErrors()) 
      .Take(50) 
      .Select(r => "\n - " + r.Table.TableName + "[" + string.Join(", ", r.Table.PrimaryKey.Select(c => r[c])) + "]: " + r.RowError)); 
    throw new ConstraintException(ex.Message + details); 
} 
Verwandte Themen