4

我正在将数据从表 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 是否能够使用默认约束?

4

2 回答 2

3

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

更新:

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

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

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

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

于 2011-05-11T17:51:40.027 回答
0

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

_sqlCommandBuilder.ConflictOption = ConflictOption.OverwriteChanges;

如果我引用MSDN 定义,您可能会阅读:

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

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

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



然后....

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

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

(引用自MSDN 网站

独特的

于 2011-05-08T11:50:35.057 回答