对数据表强制约束

本文关键字:约束 数据表 | 更新日期: 2023-09-27 17:59:50

数据集上有一个EnforceConstraints属性,指示是否应启用约束。尽管数据表也可以有约束,但我不能禁用数据表的约束。

我的情况是,我有一个数据表,我在内存中使用它,在其中一列上有一个uniqueconstraint。有时我想暂时禁用唯一约束。我该怎么做?我唯一想到的就是删除并重新添加约束。有更好的方法吗?

对数据表强制约束

我的解决方案是这个

using (IDataReader reader = ExecuteReader(sql))
            {
                DataTable dt = new DataTable();
                using (DataSet ds = new DataSet() { EnforceConstraints = false })
                {
                    ds.Tables.Add(dt);
                    dt.Load(reader, LoadOption.OverwriteChanges);
                    ds.Tables.Remove(dt);
                }
                return dt;
            }

DataTable上没有公共EnforceConstraints属性。我提出了以下禁用约束的方法之一:

  • 要暂时禁用约束,请使用方法DataTable.BeginLoadData(),然后使用方法DataTable.EndLoadData()重新启用约束
  • 将该DataTable添加到(伪)DataSet中,并将属性DataSet.EnforceConstraints设置为false

注意:禁用检查约束也会禁用有关DataColumn.AllowDBNullDataColumn.MaxLength的检查值。

基本上我所做的就是循环遍历contrin并移除它们。执行该操作并在表上重新添加约束

您可以使用约束来对DataTable中的数据实施限制,以保持数据的完整性。当DataSetSystem.Data.DataSet.EnforceConstraints属性为true时,强制执行约束。

ADO.NET中有两种约束:ForeignKeyConstraint和UniqueConstraint。默认情况下,当通过向DataSet添加DataRelation来创建两个或多个表之间的关系时,会自动创建两个约束。但是,可以通过在创建关系时指定createConstraints = fals来禁用此行为。

当您选择键列时,即在JOIN中,并且生成的表在生成的表中有多个相同的值时,通常会发生这种异常。假设您有一个具有CustID PK的客户表,并且您将该表与一个地址表连接,其中关系为1..n。客户可以有多个地址。您最终得到一个结果表,其中对所有地址重复CustID。数据表加载源模式并看到CustID是PK,因此它是唯一的,但JOIN命令生成的表在CustID列中重复了该值。然后出现异常。

如果你想处理和收集错误:

        using var tbl = new DataTable();
        using var reader = cmd.ExecuteReader();
        tbl.BeginLoadData();
        try
        {
            tbl.Load(reader);
        }
        catch (ConstraintException ex)
        {
            var sb = new StringBuilder();
            foreach (var row in tbl.GetErrors())
            {
                sb.AppendLine(row.RowError);
                foreach (var col in row.GetColumnsInError())
                {
                    var colError = col.ColumnName
                                   + ":" + row.GetColumnError(col);
                    sb.AppendLine(colError);
                }
            }
            reader.Close();
            tbl.Clear();
            tbl.Constraints.Clear();
            if (IgnoreErrors)
                tbl.Load(cmd.ExecuteReader());
            else
                throw new ConstraintException(sb.ToString(), ex);
        }
        finally
        {
            tbl.EndLoadData();
        }

"IgnoreErrors"是数据层或实体加载程序等中的一个属性。

如果你想避免错误,用"AS"重命名源列:

"SELECT A.*, C.CustID AS CustIDNew FROM Addresses AS A INNER JOIN Customer AS C ON C.CustID = A.lCustID"

问候

如果加载数据表时数据表中有数据,则可能引发异常。为了安全起见,在加载数据表之前先清除数据表,如下所示:

MyDataTable.Clear();
MyDataTable.Load(MyDataReader, LoadOption.OverwriteChanges);

这对我有效:)