Как узнать, какой столбец и значение нарушают ограничение? Сообщение об исключении не полезно вообще:
Не удалось включить ограничения. Один или больше строк содержат значения, нарушающие ненулевой, уникальный или внешний ключ ограничения.
Как узнать, какой столбец и значение нарушают ограничение? Сообщение об исключении не полезно вообще:
Не удалось включить ограничения. Один или больше строк содержат значения, нарушающие ненулевой, уникальный или внешний ключ ограничения.
Существует свойство RowError, которое вы можете проверить.
См. http://dotnetdebug.net/2006/07/16/constraintexception-a-helpful-tip/
Отредактировано, чтобы добавить эту ссылку, показывающую итерацию строк, чтобы увидеть, какие ошибки были.
http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.adonet/topic58812.aspx
Как и многие люди, у меня есть свои собственные стандартные компоненты доступа к данным, которые включают методы для возврата DataSet. Конечно, если выбрано исключение ConstraintException, DataSet не возвращается вызывающему, поэтому вызывающий не может проверить наличие ошибок строки.
То, что я сделал, это catch и 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());
}
Когда вы используете сильные типизированные данные и используете визуальный конструктор (xsd): для доступа к информации tbl.Rows [0].RowError, вам необходимо создать метод Заполнить.
Вы не можете использовать метод Get, так как DataTable создается внутри сгенерированного кода.
Я добавил код, который, как мне показалось, полезен при отладке экземпляров ConstraintException здесь
Надеюсь, что это поможет.
Для гуглеров, которым нужен фрагмент, чтобы получить более подробную информацию об исключении 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);
}