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

Я много искал, но не смог найти решение.

Я получаю ошибку:

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

я бегу DataTable.GetErrors() и увидеть, что некоторые столбцы установлены в Not NULL в базе данных SQL Compact Edition. И эти столбцы используются в LEFT OUTER JOIN запрос, поэтому они являются нулевыми, когда запрос выполняется. (Я могу получить результаты, когда я запускаю запрос в Server Explorer в VS). Ошибка возникает при попытке загрузить данные в Datatable:

using (SqlCeCommand Cmd = new SqlCeCommand("Query HERE", "Connection HERE"))
                {
                    C.Open();
                    using (SqlCeDataReader Rdr = Cmd.ExecuteReader())
                    {
                        DataTable DT = new DataTable();
                        DT.Load(Rdr);
                        return DT;
                    }
                }

Я пробовал так много решений, чтобы преодолеть это, однако я не смог решить это. Я знаю о "EnforceConstraints", однако, поскольку я не использую какой-либо набор данных, я не могу изменить это свойство.

3 ответа

Решение

Мне удалось решить эту проблему путем получения схемы таблицы, итерации по строкам таблицы схемы (которые являются столбцами фактической таблицы) и созданию столбца с такими же свойствами, что и у столбца схемы (единственное отличие состоит в том, чтобы задать для AllowDBNull нового столбца значение true и Unique и AutoIncrement в false) и, наконец, добавление нового столбца в новый массив данных, который позже будет заполнен данными нашей фактической таблицы (с помощью DataReader, чтобы получить только данные, а не схему).

Вот код:

using (SqlCeConnection C = new SqlCeConnection(DBStr))
            using (Cmd)
            {   //using SqlCeCommand
                Cmd.Connection = C;
                C.Open();
                using (SqlCeDataReader Rdr = Cmd.ExecuteReader())
                {
                    //Create datatable to hold schema and data seperately
                    //Get schema of our actual table
                    DataTable DTSchema = Rdr.GetSchemaTable();
                    DataTable DT = new DataTable();
                    if (DTSchema != null)
                        if (DTSchema.Rows.Count > 0)
                            for (int i = 0; i < DTSchema.Rows.Count; i++)
                            {
                                //Create new column for each row in schema table
                                //Set properties that are causing errors and add it to our datatable
                                //Rows in schema table are filled with information of columns in our actual table
                                DataColumn Col = new DataColumn(DTSchema.Rows[i]["ColumnName"].ToString(), (Type)DTSchema.Rows[i]["DataType"]);
                                Col.AllowDBNull = true;
                                Col.Unique = false;
                                Col.AutoIncrement = false;
                                DT.Columns.Add(Col);
                            }

                    while (Rdr.Read())
                    {
                        //Read data and fill it to our datatable
                        DataRow Row = DT.NewRow();
                        for (int i = 0; i < DT.Columns.Count; i++)
                        {
                            Row[i] = Rdr[i];
                        }
                        DT.Rows.Add(Row);
                    }
                    //This is our datatable filled with data
                    return DT;
                }
            }

Это также может произойти, если вы загружаете данные из таблицы, где некоторые строки различаются только в верхнем и нижнем регистре. В моем случае это произошло с использованием SQLite (Microsoft.Data.SQLite). Я мог бы исправить это, установивDataTable.CaseSensitive = true. Пример кода на С#:

      protected virtual DataTable Get(string sqlQuery)
{
    DataTable dataTable = new DataTable() { CaseSensitive = true };
    DbProviderFactory factory = SqliteFactory.Instance;
    using (DbConnection connection = GetConnection(factory))
    {
        using (DbCommand command = factory.CreateCommand())
        {
            command.Connection = connection;
            command.CommandText = sqlQuery;

            connection.Open();
            dataTable.Load(command.ExecuteReader());
        }
    }

    return dataTable;
}

В случае, если он поймает кого-то еще; в моей базе данных SQLite у меня были записи NULL, хранящиеся в виде строк ( "NULL"), простое исправление данных сработало.

Это специфичная для SQLite проблема, поскольку вы можете смешивать типы данных в столбцах!

Другие вопросы по тегам