【问题标题】:Handling XSD Dataset ConstraintExceptions处理 XSD 数据集约束异常
【发布时间】:2010-09-07 11:11:21
【问题描述】:

有没有人有任何处理 XSD 数据集抛出的 ConstraintExceptions 的技巧?

这是神秘消息的例外:

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

【问题讨论】:

    标签: xsd dataset constraintexception


    【解决方案1】:

    我最近发现的一些技巧。

    1. 使用 TableAdapter FillByDataXXXX() 方法而不是 GetDataByXXXX() 方法要好得多,因为可以查询传递给 fill 方法的 DataTable 以获取线索:

      • DataTable.GetErrors() 返回一个 错误的 DataRow 实例数组
      • DataRow.RowError 包含一个 行错误说明
      • DataRow.GetColumnsInError() 返回 DataColumn 实例的数组 错误
    2. 最近,我将一些询问代码封装到 ConstraintException 的子类中,结果证明这是一个有用的调试起点。

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

    输出:

    DetailedConstraintException:表格填充失败
    针对 ConstraintExceptionHelper.DataSet+fooDataTable [foo]
    报告的错误 错误列:[1]
    [PRODUCT_ID] - 受影响的总行数:1085
    行错误:[4]
    [列 'PRODUCT_ID' 被限制为唯一。值“1”已存在。] - 受影响的总行数:1009
    [列 'PRODUCT_ID' 被限制为唯一。值“2”已存在。] - 受影响的总行数:20
    [列 'PRODUCT_ID' 被限制为唯一。值“4”已存在。] - 受影响的总行数:34
    [列 'PRODUCT_ID' 被限制为唯一。值“6”已存在。] - 受影响的总行数:22
    ----> System.Data.ConstraintException:无法启用约束。一行或多行包含违反非空、唯一或外键约束的值。

    我不知道堆栈溢出答案中是否包含太多代码,但这里是完整的 C# 类。 免责声明:这对我有用,请随意使用/修改。

    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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-04
      • 2017-05-16
      • 2012-06-01
      • 2019-03-08
      • 1970-01-01
      相关资源
      最近更新 更多