代码之家  ›  专栏  ›  技术社区  ›  Jonathan Webb

处理XSD数据集约束概念

  •  7
  • Jonathan Webb  · 技术社区  · 16 年前

    有没有人对处理XSD数据集抛出的约束概念有什么建议?

    这是神秘消息的例外情况:

    System.Data.ConstraintException : Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
    
    1 回复  |  直到 16 年前
        1
  •  19
  •   Jonathan Webb    16 年前

    我最近发现了一些提示。

      • GetErrors()返回一个 错误的DataRow实例数组
      • DataRow.RowError包含一个
      • GetColumnsInError()返回 错误

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

    输出:


    ConstraintExceptionHelper.DataSet+fooDataTable[foo]报告的错误
    错误列:[1]


    [列'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;
        }
    }