Question

Comment puis-je savoir quelle colonne et quelle valeur enfreignent la contrainte? Le message d'exception n'est pas du tout utile:

  

Impossible d'activer les contraintes. Un ou   plus de lignes contiennent des valeurs violant   clé non nulle, unique ou étrangère   contraintes.

Était-ce utile?

La solution

Il existe une propriété appelée RowError que vous pouvez vérifier.

Voir http://dotnetdebug.net/2006/07/ 16 / constraintexception-un-conseil-utile /

Modifié pour ajouter ce lien montrant l'itération de lignes pour voir celles qui ont eu des erreurs.

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

Autres conseils

Comme beaucoup de gens, j’ai mes propres composants d’accès aux données standard, qui incluent des méthodes pour renvoyer un DataSet. Bien sûr, si une exception ConstraintException est levée, le DataSet n'est pas renvoyé à l'appelant. L'appelant ne peut donc pas rechercher les erreurs de ligne.

Ce que j'ai fait est de capturer et de rediffuser ConstraintException dans de telles méthodes, en enregistrant les détails d'erreur de ligne, comme dans l'exemple suivant (qui utilise Log4Net pour la journalisation):

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

Lorsque vous utilisez un ensemble de données fortement typé et utilisez le concepteur visuel (xsd): pour accéder aux informations tbl.Rows [0] .RowError , vous devez créer le remplissage méthode.

Vous ne pouvez pas utiliser la méthode Get , car le DataTable est instancié dans le code généré.

J'ai ajouté du code que j'ai trouvé utile pour le débogage d'occurrences de ConstraintException ici

J'espère que cela vous aidera.

Pour les utilisateurs qui souhaitent un extrait pour obtenir plus de détails sur l’exception 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);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top