MySqlDataReader:DataTable.Fill(reader) 抛出 ConstraintException

发布于 2024-12-07 02:45:23 字数 2607 浏览 3 评论 0原文

我有两个表 ordersorderdetails

表 orders (PK = id, orderno 上的唯一索引)

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

表 orderdetails (PK = id)

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

现在我想用以下命令查询数据:

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

INNER JOIN 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]

是一个orderno 列上的 UniqueConstraints。可能是因为

reader.GetSchemaTable() 

orderno 有一个 IsUnique=true 条目(在基表中为 true,但对于连接查询则不然)。

更糟糕的是,这也没有帮助:

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

有什么想法如何解决这个问题吗?

堆栈跟踪:

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)

I have two tables orders and orderdetails

table orders (PK = id, UNIQUE index on orderno)

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

table orderdetails (PK = id)

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

Now I want to query the data with:

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

INNER JOIN orderdetails od ON o.orderno = od.order

which returns:

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

However If I use the following code to load the result into a DataTable it fails:

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

The problem is, that

table.Constraints[0]

is a UniqueConstraints on the orderno column. Propably because

reader.GetSchemaTable() 

has a IsUnique=true entry for orderno (which is true in the base table, but not true for the join query).

Even worse, that doesn't help either:

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

Any ideas how to fix this?

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我偏爱纯白色 2024-12-14 02:45:23

我遇到了同样的问题,但通过使用这篇文章中的解决方法解决了它: 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();

I had the same problem but got it fixed by using the workaround from this post: http://bugs.mysql.com/bug.php?id=65065 (at bottom):

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();
枕头说它不想醒 2024-12-14 02:45:23

我刚刚发现,

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);

I just figured out, that

table.Fill(reader)

does not create the constraint, if I already added the columns.

So I fixed this by using a nice little extension method:

    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);
    }

Usage:

table.Fill(reader, true);
吹泡泡o 2024-12-14 02:45:23

有一种简单的肮脏方法可以修复它 - 使用 concat 函数的唯一约束包围查询中的列:

var commandText = "SELECT CONCAT(o.orderno, ''), od.item, od.qty ...";

There is simple dirty way how to fix it - surround column in query with unique contraint with concat function:

var commandText = "SELECT CONCAT(o.orderno, ''), od.item, od.qty ...";
誰認得朕 2024-12-14 02:45:23

我今天遇到了同样的错误并想分享。我的问题是具有 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);

I had the same error today and want to share.My problem was a column with a LONGTEXT type. If I include LONGTEXT column in my query and tried to load dataset without specifying column names exception was thrown. Based on SchlaWiener's code I rewrote the code as follows and everything is fine now.

MySqlDataReader resultSet = cmd.ExecuteReader();
dt.Columns.Clear();
for (int i = 0; i < resultSet.FieldCount; i++)
{
    dt.Columns.Add(resultSet.GetName(i));
}
dt.Load(resultSet);
穿越时光隧道 2024-12-14 02:45:23

MySQL 允许唯一索引中存在多个空值。这会导致填充时出现 ConstraintException。如何修复:在“table.Constraints”列表中找到此约束并将其删除或清除所有约束。

MySQL allows multiple null values in unique indexes. This causes ConstraintException on fill. How to fix: find this constraint in the 'table.Constraints' list and remove it or just clear all constraints.

划一舟意中人 2024-12-14 02:45:23

我在查询中遇到了类似的问题,当使用 MYSQL Reader 加载 Datatable () 时,它生成错误 NON-NULL、UNIQUE 或 FOREIGN-KEY。

最后我通过更改MySQL Connector.NET版本解决了这个问题。

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

I had a similar problem with the queries, when loading the Datatable () with the MYSQL Reader it generated error NON-NULL, UNIQUE or FOREIGN-KEY.

In the end I solved it by changing the MySQL Connector.NET version.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文