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 проблема, поскольку вы можете смешивать типы данных в столбцах!