6

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)

6 Answers 6

11

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();
Sign up to request clarification or add additional context in comments.

Comments

7

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

Comments

2

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 ...";

Comments

2

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

Comments

0

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.

2 Comments

Multiple null values aren't the problem. The table.Load() method creates a Contraint on Orderno because the reader.GetSchemaTable() has IsUnique = true for the Orderno column, wich is wrong for a Join query.
I thought about that, too. But if I use the overload that accepts a FillError delegate, it doesn't fire. Can't tell why, because that's what I should expect.
0

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/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.