处理XSD数据集ConstraintExceptions
时间:2020-03-05 18:45:59 来源:igfitidea点击:
有没有人有任何技巧来处理XSD数据集引发的ConstraintExceptions?
这是神秘消息的例外:
System.Data.ConstraintException : Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
解决方案
回答
我最近发现了一些技巧。
- DataRow.RowError包含行错误的描述
- DataRow.GetColumnsInError()返回错误的DataColumn实例数组
- 最近,我将一些查询代码包装到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 : table fill failed Errors reported for ConstraintExceptionHelper.DataSet+fooDataTable [foo] Columns in error: [1] [PRODUCT_ID] - total rows affected: 1085 Row errors: [4] [Column 'PRODUCT_ID' is constrained to be unique. Value '1' is already present.] - total rows affected: 1009 [Column 'PRODUCT_ID' is constrained to be unique. Value '2' is already present.] - total rows affected: 20 [Column 'PRODUCT_ID' is constrained to be unique. Value '4' is already present.] - total rows affected: 34 [Column 'PRODUCT_ID' is constrained to be unique. Value '6' is already present.] - total rows affected: 22 ----> System.Data.ConstraintException : Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
我不知道这是否太多代码无法包含在Stack Overflow答案中,但这是完整的Cclass。
免责声明:这对我有效,请随意使用/修改。
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; } }