Domanda

Come posso sapere quale colonna e valore sta violando il vincolo? Il messaggio di eccezione non è affatto utile:

  

Impossibile abilitare i vincoli. Uno o   più righe contengono valori che violano   chiave non nulla, univoca o esterna   vincoli.

È stato utile?

Soluzione

C'è una proprietà chiamata RowError che puoi controllare.

Vedi http://dotnetdebug.net/2006/07/ 16 / constraintexception-a-utile-tip /

Modificato per aggiungere questo collegamento che mostra l'iterazione di righe per vedere quali errori contenevano.

http://www.devnewsgroups.net/ gruppo / microsoft.public.dotnet.framework.adonet / topic58812.aspx

Altri suggerimenti

Come molte persone, ho i miei componenti standard di accesso ai dati, che includono metodi per restituire un DataSet. Naturalmente, se viene generata una ConstraintException, il DataSet non viene restituito al chiamante, quindi il chiamante non può verificare la presenza di errori di riga.

Quello che ho fatto è catturare e riproporre ConstraintException in tali metodi, registrando i dettagli dell'errore di riga, come nell'esempio seguente (che utilizza Log4Net per la registrazione):

...
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());
}

Quando si utilizza un set di dati tipizzato forte e si utilizza Visual Designer (xsd): per accedere a tbl.Rows [0] .RowError , è necessario creare le Fill metodo.

Non puoi utilizzare il metodo Get , poiché la DataTable è istanziata nel codice generato.

Ho aggiunto del codice che ho trovato utile nel debug delle occorrenze di ConstraintException qui

Spero che questo aiuti.

Per i googler che desiderano uno snippet per ottenere maggiori dettagli su ConstraintException:

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top