Question

Quelqu'un a-t-il des conseils pour gérer les ConstraintExceptions levées par les ensembles de données XSD ?

C'est l'exception avec le message énigmatique :

System.Data.ConstraintException : Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
Était-ce utile?

La solution

Quelques conseils que j'ai trouvés récemment.

  1. Il est préférable d'utiliser les méthodes TableAdapter FillByDataXXXX() au lieu des méthodes GetDataByXXXX() car le DataTable passé dans la méthode fill peut être interrogé pour obtenir des indices :

    • DataTable.getErrors () renvoie un tableau d'instances de données de données dans l'erreur
    • Datarow.Rowerror contient une description de l'erreur de ligne
    • Datarow.getColumnSiNerror () renvoie un tableau d'instances Datacolumn en erreur
  2. Récemment, j'ai intégré du code d'interrogation dans une sous-classe de ConstraintException qui s'est avérée être un point de départ utile pour le débogage.

Exemple d'utilisation C# :

Example.DataSet.fooDataTable table = new DataSet.fooDataTable();

try
{
    tableAdapter.Fill(table);
}
catch (ConstraintException ex)
{
    // pass the DataTable to DetailedConstraintException to get a more detailed Message property
    throw new DetailedConstraintException("error filling table", table, ex);
}

Sortir:

DétailConstraintException :échec du remplissage du tableau
Erreurs signalées pour ConstraintExceptionHelper.DataSet+fooDataTable [foo]
Colonnes en erreur :[1]
[PRODUCT_ID] – nombre total de lignes concernées :1085
Erreurs de ligne :[4]
[La colonne « PRODUCT_ID » doit être unique.La valeur « 1 » est déjà présente.] - nombre total de lignes concernées :1009
[La colonne « PRODUCT_ID » doit être unique.La valeur « 2 » est déjà présente.] - nombre total de lignes concernées :20
[La colonne « PRODUCT_ID » doit être unique.La valeur « 4 » est déjà présente.] - nombre total de lignes concernées :34
[La colonne « PRODUCT_ID » doit être unique.La valeur « 6 » est déjà présente.] - nombre total de lignes concernées :22
----> System.Data.ConstraintException :Échec de l'activation des contraintes.Une ou plusieurs lignes contiennent des valeurs violant des contraintes non nulles, uniques ou de clé étrangère.

Je ne sais pas si c'est trop de code à inclure dans une réponse Stack Overflow, mais voici la classe C# dans son intégralité.Clause de non-responsabilité:cela fonctionne pour moi, n'hésitez pas à utiliser/modifier selon vos besoins.

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;

namespace ConstraintExceptionHelper
{

    /// <summary>
    /// Subclass of ConstraintException that explains row and column errors in the Message property
    /// </summary>
    public class DetailedConstraintException : ConstraintException
    {

        private const int InitialCountValue = 1;


        /// <summary>
        /// Initialises a new instance of DetailedConstraintException with the specified string and DataTable
        /// </summary>
        /// <param name="message">exception message</param>
        /// <param name="ErroredTable">DataTable in error</param>
        public DetailedConstraintException(string message, DataTable erroredTable)
            : base(message)
        {
            ErroredTable = erroredTable;
        }


        /// <summary>
        /// Initialises a new instance of DetailedConstraintException with the specified string, DataTable and inner Exception
        /// </summary>
        /// <param name="message">exception message</param>
        /// <param name="ErroredTable">DataTable in error</param>
        /// <param name="inner">the original exception</param>
        public DetailedConstraintException(string message, DataTable erroredTable, Exception inner)
            : base(message, inner)
        {
            ErroredTable = erroredTable;
        }


        private string buildErrorSummaryMessage()
        {
            if (null == ErroredTable) { return "No errored DataTable specified"; }
            if (!ErroredTable.HasErrors) { return "No Row Errors reported in DataTable=[" + ErroredTable.TableName + "]"; }

            foreach (DataRow row in ErroredTable.GetErrors())
            {
                recordColumnsInError(row);
                recordRowsInError(row);
            }

            StringBuilder sb = new StringBuilder();

            appendSummaryIntro(sb);
            appendErroredColumns(sb);
            appendRowErrors(sb);

            return sb.ToString();
        }


        private void recordColumnsInError(DataRow row)
        {
            foreach (DataColumn column in row.GetColumnsInError())
            {
                if (_erroredColumns.ContainsKey(column.ColumnName))
                {
                    _erroredColumns[column.ColumnName]++;
                    continue;
                }

                _erroredColumns.Add(column.ColumnName, InitialCountValue);
            }
        }


        private void recordRowsInError(DataRow row)
        {
            if (_rowErrors.ContainsKey(row.RowError))
            {
                _rowErrors[row.RowError]++;
                return;
            }

            _rowErrors.Add(row.RowError, InitialCountValue);
        }


        private void appendSummaryIntro(StringBuilder sb)
        {
            sb.AppendFormat("Errors reported for {1} [{2}]{0}", Environment.NewLine, ErroredTable.GetType().FullName, ErroredTable.TableName);
        }


        private void appendErroredColumns(StringBuilder sb)
        {
            sb.AppendFormat("Columns in error: [{1}]{0}", Environment.NewLine, _erroredColumns.Count);

            foreach (string columnName in _erroredColumns.Keys)
            {
                sb.AppendFormat("\t[{1}] - rows affected: {2}{0}",
                                Environment.NewLine,
                                columnName,
                                _erroredColumns[columnName]);
            }
        }


        private void appendRowErrors(StringBuilder sb)
        {
            sb.AppendFormat("Row errors: [{1}]{0}", Environment.NewLine, _rowErrors.Count);

            foreach (string rowError in _rowErrors.Keys)
            {
                sb.AppendFormat("\t[{1}] - rows affected: {2}{0}",
                                Environment.NewLine,
                                rowError,
                                _rowErrors[rowError]);
            }
        }


        /// <summary>
        /// Get the DataTable in error
        /// </summary>
        public DataTable ErroredTable
        {
            get { return _erroredTable; }
            private set { _erroredTable = value; }
        }


        /// <summary>
        /// Get the original ConstraintException message with extra error information
        /// </summary>
        public override string Message
        {
            get { return base.Message + Environment.NewLine + buildErrorSummaryMessage(); }
        }


        private readonly SortedDictionary<string, int> _rowErrors = new SortedDictionary<string, int>();
        private readonly SortedDictionary<string, int> _erroredColumns = new SortedDictionary<string, int>();
        private DataTable _erroredTable;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top