C# 数据表上的强制约束

C# 数据表上的强制约束,c#,datatable,strongly-typed-dataset,constraints,C#,Datatable,Strongly Typed Dataset,Constraints,数据集上的EnforceConstraints属性指示是否应启用约束。虽然datatable也可以有约束,但我不能禁用datatable的约束 我的情况是,我在内存中使用了datatable,其中一列上有一个uniqueconstraint。有时我想暂时禁用唯一约束。我该怎么做?我唯一想到的就是删除并重新添加约束。有更好的方法吗?您可以使用约束对数据表中的数据实施限制,以保持数据的完整性。当数据集的System.Data.DataSet.EnforceConstraints属性为true时,将强

数据集上的EnforceConstraints属性指示是否应启用约束。虽然datatable也可以有约束,但我不能禁用datatable的约束


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

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


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

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

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

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

这对我有效:)

数据表上没有公共
强制约束
属性。我建议使用以下方法之一禁用约束:

  • 要临时禁用约束,请使用方法
    DataTable.BeginLoadData()
    ,然后
    DataTable.EndLoadData()
    重新启用约束
  • 将该数据表添加到(虚拟)数据集,并将属性
    DataSet.EnforceConstraints
    设置为false
注意:禁用检查约束也会禁用有关
DataColumn.AllowDBNull
DataColumn.MaxLength
的检查值。我的解决方案是

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

当您选择键列(即在联接中)并且结果表中有多个相同值时,通常会发生这种异常。 假设您有一个CustID PK的customer表,并且您用一个地址表连接这个表,其中关系为1..n。客户可以有多个地址。您将得到一个结果表,其中CustID将对所有地址重复。 datatable加载源模式,并看到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”:


关于

这个问题是关于暂时禁用约束的……感谢您的解释,虽然这对我来说很有效,但我只在使用mysql连接器时遇到过这个问题。拖网了很多线程,但只有这一个解决了它,因为我调用“ShowProcessList”,所以无法控制output@Downvoter:请你添加一条评论,解释你投反对票的原因好吗?这可能对某人有帮助。
"SELECT A.*, C.CustID AS CustIDNew FROM Addresses AS A INNER JOIN Customer AS C ON C.CustID = A.lCustID"