2008-09-26 2 views
31

Как узнать, какой столбец и значение нарушают ограничение? Сообщение об исключении не полезно вообще:Какие триггеры ConstraintException при загрузке DataSet?

Не удалось включить ограничения. Один или строк содержат значения, нарушающие непустые, уникальные или внешние ключи .

+2

Я дам вам больше вверх голосов, если бы мог. Это тоже шип в моей стороне. – 2008-09-26 15:19:56

ответ

20

Как и многие люди, у меня есть свои собственные компоненты доступа к стандартным данным, которые включают в себя методы возвращают DataSet. Конечно, если исключение ConstraintException выбрано, DataSet не возвращается вызывающему, поэтому вызывающий не может проверить наличие ошибок строки.

Что я сделал это поймать и Rethrow ConstraintException в таких методах регистрации сведения об ошибках строки, как показано в следующем примере (который использует Log4Net для регистрации):

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

Ваш метод LogErrors замечательный! Буквально спас меня сегодня. – Dave 2010-04-14 22:36:55

1

Я добавил код, что я» ve признан полезным при отладке ConstraintException вхождения here

Надеюсь, это поможет.

3

При использовании сильных типизированного набора данных и используются визуальный конструктор (XSD): доступ к tbl.Rows [0] .RowError информации, вам нужно создать Fill метода.

не может использовать метод Get, т.к.

+0

как вы сказали, вам нужно заполнить. Очень странно; зачем мне нужно заполнять заявление, когда я получаю только некоторые данные (основной выбор). Где-то внутри мысли этот метод заливки используется .net. После того, как я создал метод Fill (без изменений на get), он сработал. – Obelix 2013-12-30 14:29:12

1

Для Googlers, которые хотят сниппет, чтобы получить более подробную информацию о 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); 
} 
Смежные вопросы