Что вызывает ConstraintException при загрузке DataSet? - PullRequest
31 голосов
/ 26 сентября 2008

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

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

Ответы [ 5 ]

20 голосов
/ 26 сентября 2008

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

Что я сделал, так это перехватил и сгенерировал 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());
}
11 голосов
/ 26 сентября 2008

Существует свойство RowError, которое вы можете проверить.

См. http://dotnetdebug.net/2006/07/16/constraintexception-a-helpful-tip/

Отредактировано, чтобы добавить эту ссылку, показывающую итерацию строк, чтобы увидеть, какие были ошибки.

http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework.adonet/topic58812.aspx

3 голосов
/ 29 октября 2008

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

Вы не можете использовать метод Get , поскольку DataTable создается в сгенерированном коде.

1 голос
/ 11 мая 2016

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

Я добавил некоторый код, который оказался полезным для отладки вхождений ConstraintException здесь

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...