DataTable.Load,一个或多个行包含违反非空、唯一或外键约束的值。

4

我搜索了很多,但找不到解决方案。

我收到以下错误消息:

无法启用约束。一个或多个行包含违反非空、唯一或外键约束的值。

我运行DataTable.GetErrors(),发现在SQL Compact Edition数据库中,一些列被设置为Not NULL,而这些列在LEFT OUTER JOIN查询中使用,所以当运行查询时,它们为空。(当我在VS中运行 Server Explorer 时会得到结果) 当尝试在数据表格中加载数据时出现错误:

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(强制执行约束)",但由于我没有使用任何数据集,我无法更改该属性。


我以前经常看到这种情况,通常是由一个查询填充的 DataSet 返回了两个 DataTables,而关键字要么为 NULL,要么在两个数据表之间无法正确连接。 - Kane
从代码中可以看出只有一个数据表。正如我所说,我没有使用任何数据集。 - tozlu
请查看我在旧帖子 https://stackoverflow.com/questions/7807681/getting-a-constraints-exception-when-loading-a-datareader-in-a-datatable/44533184#44533184 中的新答案,其中提供了一种适用于某些情况的简单解决方法。虽然两个帖子都包含有价值的信息,但这个问题可能符合那个帖子的重复标准。 - SQLServerSteve
可能是在DataTable中加载DataReader时出现约束异常的重复问题。 - SQLServerSteve
3个回答

10

通过获取表的模式,迭代模式表的行(实际表的列),创建一个具有与模式列相同属性的列(仅区别是将新列的AllowDBNull设置为true并将Unique和AutoIncrement设置为false),最后将新列添加到一个新的datatable中,该datatable稍后将填充我们实际表的数据(通过使用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;
                }
            }

0

如果有其他人遇到同样的问题,我在SQLite数据库中将NULL条目存储为字符串("NULL"),只需修复数据即可解决。

这是SQLite特定的问题,因为您可以在列中混合使用数据类型!


0

如果您从一个表中加载数据,其中某些字符串仅在大小写上有所不同,也可能会发生这种情况。在我的情况下,我使用SQLite(Microsoft.Data.SQLite)时遇到了这个问题。我可以通过设置DataTable.CaseSensitive = true来解决它。以下是C#的代码示例:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接