【问题标题】:ADO.NET CommandBuilder, InsertCommand and Default ConstraintsADO.NET CommandBuilder、InsertCommand 和默认约束
【发布时间】:2011-08-17 14:53:24
【问题描述】:

我正在将数据从表 A 复制到表 B。 表 B 有一个 可为空 列,该列的 默认约束 值为 0。 一般来说,我使用以下访问器设置列的值。

public object this[string columnName]
{
    get { return DataTable.Rows[CurrentRow][columnName]; }
    set { DataTable.Rows[CurrentRow][columnName] = value; }
}

但我确实设置我的可为空列 X。

当我插入整行时,不使用默认值。为可空列插入 NULL 而不是 0。

_sqlCommandBuilder = new SqlCommandBuilder(_sqlDataAdapter);
_sqlCommandBuilder.ConflictOption = ConflictOption.OverwriteChanges;
_sqlCommandBuilder.SetAllValues = false;
_sqlDataAdapter.Update(DataTable);

我也得到了架构:

_sqlDataAdapter.Fill(DataTable);
_sqlDataAdapter.FillSchema(_dataTable, SchemaType.Mapped);

为什么 ADO.NET 为我的 X 列设置 NULL,虽然我没有设置它?

我以为当我不设置 X 列的值时,ADO.NET 从给定的约束中获取默认值。

ADO.NET CommandBuilder 是否能够使用默认约束?

【问题讨论】:

    标签: c# ado.net constraints sqlcommandbuilder


    【解决方案1】:

    您不需要使用CommandBuilder 来实现DataAdapter 的更新方法。 CommandBuilder 充满了问题。您可以将DataAdapter.SelectCommandDataAdapter.UpdateCommand 属性设置为直接指定sql 的DbCommand 对象。这避免了CommandBuilder 生成正确sql 语句的能力所固有的问题。

    更新:

    CommandBuilder 无法知道您要使用默认值。它所做的只是生成一个插入语句,如果有一个列,它将为插入语句生成它。如果该列是插入语句的一部分,那么为该列提供的任何值,即使是空值,都将被插入。默认值适用于未将其包含在插入语句中的情况。无论您如何尝试插入项目,无论是否使用 CommandBuilder,它都不会将 null 转换为默认值。

    继续尝试使用 CommandBuilder 只会让您更加痛苦。它甚至无法处理其 select 子句中的简单连接语句。它还需要一个主键。如果违反其中任何一个,则它无法生成正确的更新、插入和删除语句。只有两个提供者,Sql Server 和 Oracle,曾经实现过这个类,而众所周知,Oracle 有一些错误,除了上述基本问题之外从未修复过。

    如果您使用了两个 DbCommand 对象,一个用于选择,一个用于插入,然后通过 DbDataReader 循环选择 DbCommand 的输出,您可以轻松地检查该列中的 null 并将默认值零提供给插入 DbCommand,因为您知道它是什么。了解数据库规则并在必要时使用它们并不违反任何类型的代码组织规则。为了编写这种代码,你必须知道数据库中有什么。

    如果您有 sql server 2005 或更高版本,另一个建议是使用 INSERT INTO .. SELECT 语句。如果您的 sql 足够好,您可以使用 CASE 子句来创建一条 sql 语句。

    【讨论】:

    • 我不想手动创建更新、创建、删除语句。我希望我正确地理解了你。如果没有,请告诉我:)
    • 您会认为当您向表中添加一行时,只有您设置的列会出现在插入语句中,从而允许默认值正确显示。这在 ADODB 中有效,我很惊讶 ADO.NET 失去了这个功能。
    【解决方案2】:

    一个小问题,看起来很明显,但实际上很棘手。

    _sqlCommandBuilder.ConflictOption = ConflictOption.OverwriteChanges;
    

    如果我引用MSDN definition,你可能会读到:

    "If no PrimaryKey is defined, all searchable columns are included in the WHERE clause."
    

    我的一个朋友,曾经在一些camses中定义IDENTITY(1, 1)而不是主键。

    小问题是,您是否在“更新”表 B 中使用主键??



    那么……

    要添加信息,SqlAdapter.FillSchema 不使用默认值 以下是 FillSchema 检索到的信息:

    AllowDBNull 
    AutoIncrement.You must set AutoIncrementStep and AutoIncrementSeed separately.
    MaxLength 
    ReadOnly 
    Unique
    

    (引用自MSDN site

    独一无二的

    【讨论】:

    • 主键已定义,但您的第二个信息提供信息,谢谢:) 但它并没有解决我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-26
    • 2020-12-11
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多