ADO.NET CommandBuilder,InsertCommand和Default Constraints

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

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

但我没有设置我的可空列X.

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

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

我也得到了架构:

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

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

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

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

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

更新:

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

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

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

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

一个小问题,看似显而易见,但事实上它很棘手。

 _sqlCommandBuilder.ConflictOption = ConflictOption.OverwriteChanges; 

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

 "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网站 )

独特