MySqlDataReader: DataTable.Fill (reader) генерирует исключение ConstraintException - PullRequest
3 голосов
/ 28 сентября 2011

У меня есть две таблицы orders и orderdetails

таблицы заказов (PK = идентификатор, уникальный индекс по номеру заказа)

|id|orderno|
| 1|1000   |
| 2|1001   |

таблицы OrderDtails (PK = идентификатор)

|id|orderid|item|qty|
| 1|      1|ABC |  3|
| 2|      1|XYZ |  4|

Теперь я хочу запросить данные с помощью:

SELECT o.orderno, od.item, od.qty
  FROM orders o

ВНУТРЕННЕЕ ПОДКЛЮЧЕНИЕ OrderDetails od ON o.orderno = od.order

, который возвращает:

|orderno|item|qty|
|1000   |ABC |  3|
|1000   |XYZ |  4|

Однако, если я использую следующий код для загрузки результата в DataTable, он завершается ошибкой:

var connectionString = "Server=localhost;Database=orders;Uid=root;";
var commandText = "SELECT o.orderno, od.item, od.qty" + Environment.NewLine +
                  "FROM orders o" + Environment.NewLine +
                  "INNER JOIN orderdetails od ON o.orderno = od.order";

var reader = MySqlHelper.ExecuteReader(connectionString, commandText);
var table = new DataTable("OrdersQuery");
table.Fill(reader); // throws ConstraintException

Проблема в том, что

table.Constraints[0]

представляет собой UniqueConstraintsна столбце заказа.Вероятно потому, что

reader.GetSchemaTable() 

имеет запись IsUnique=true для orderno (что верно в базовой таблице, но не верно для запроса на соединение).

Еще хуже, это не такПомогите либо:

table.BeginLoadData(); // msdn docs claim that this should disable constraints
table.Load(reader);
table.EndLoadData();

Есть идеи как это исправить?

StackTrace:

System.Data.ConstraintException Was Unhandled.
  Message=Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
  Source=System.Data
  StackTrace:
       bei System.Data.DataTable.EnableConstraints()
       bei System.Data.DataTable.set_EnforceConstraints(Boolean value)
       bei System.Data.DataTable.EndLoadData()
       bei System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
       bei System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
       bei System.Data.Common.LoadAdapter.FillFromReader(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
       bei System.Data.DataTable.Load(IDataReader reader, LoadOption loadOption, FillErrorEventHandler errorHandler)
       bei System.Data.DataTable.Load(IDataReader reader)

Ответы [ 6 ]

8 голосов
/ 20 февраля 2013

У меня была та же проблема, но я исправил ее с помощью обходного пути из этого поста: http://bugs.mysql.com/bug.php?id=65065 (внизу):

cmd.CommandText = "SELECT cam.no_serie, t.mnt FROM trx t LEFT JOIN camn cam USING(id_camn) ";
    MySqlDataReader dr = cmd.ExecuteReader();
    DataSet ds = new DataSet();
    DataTable dataTable = new DataTable();
    ds.Tables.Add(dataTable);
    ds.EnforceConstraints = false;
    dataTable.Load(dr);
    dr.Close();
6 голосов
/ 28 сентября 2011

Я только что понял, что

table.Fill(reader)

не создает ограничение, если я уже добавил столбцы.

Так что я исправил это с помощью небольшого метода расширения:

    public static void Load(this DataTable table, IDataReader reader, bool createColumns)
    {

        if (createColumns)
        {
            table.Columns.Clear();
            var schemaTable = reader.GetSchemaTable();
            foreach (DataRowView row in schemaTable.DefaultView)
            {
                var columnName = (string)row["ColumnName"];
                var type = (Type)row["DataType"];
                table.Columns.Add(columnName, type);
            }
        }

        table.Load(reader);
    }

Использование:

table.Fill(reader, true);
2 голосов
/ 17 ноября 2013

У меня была такая же ошибка сегодня, и я хочу поделиться. Моя проблема - столбец с типом LONGTEXT.Если я включаю столбец LONGTEXT в свой запрос и пытаюсь загрузить набор данных без указания имен столбцов, исключение выдается.На основе кода SchlaWiener я переписал код следующим образом, и теперь все в порядке.

MySqlDataReader resultSet = cmd.ExecuteReader();
dt.Columns.Clear();
for (int i = 0; i < resultSet.FieldCount; i++)
{
    dt.Columns.Add(resultSet.GetName(i));
}
dt.Load(resultSet);
2 голосов
/ 15 февраля 2012

Существует простой грязный способ, как это исправить - окружить столбец в запросе уникальным противопоставлением с функцией concat:

var commandText = "SELECT CONCAT(o.orderno, ''), od.item, od.qty ...";
0 голосов
/ 16 октября 2018

У меня была похожая проблема с запросами, при загрузке Datatable () с помощью MYSQL Reader он генерировал ошибку NON-NULL, UNIQUE или FOREIGN-KEY.

В конце я решил ее, изменивMySQL Connector. NET версия.

https://dev.mysql.com/downloads/connector/net/

0 голосов
/ 28 сентября 2011

MySQL допускает множественные нулевые значения в уникальных индексах.Это вызывает ConstraintException при заполнении.Как исправить: найдите это ограничение в списке 'table.Constraints' и удалите его или просто удалите все ограничения.

...