ADO.NET命令生成器,插入命令和默认约束

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能否使用默认约束?
2个回答

3
您不需要使用CommandBuilder来实现DataAdapter的更新方法。 CommandBuilder存在很多问题。您可以将DataAdapter.SelectCommandDataAdapter.UpdateCommand属性设置为DbCommand对象,以直接指定SQL。这样可以避免CommandBuilder在生成正确的SQL语句方面存在的问题。
更新:
没有办法让CommandBuilder知道您想要使用默认值。它只是生成一个插入语句,如果有一列将为插入语句生成该列。如果该列是插入语句的一部分,则为该列提供的任何值(即使是null)都将被插入。默认值用于您在插入语句中未包含它的情况。无论如何尝试插入项目(无论是使用CommandBuilder还是其他方式),它都不会将null转换为默认值。
继续使用CommandBuilder的做法只会给您带来更多烦恼。它甚至不能处理简单的联接语句。它还需要一个主键。如果违反了其中任一条,则无法生成正确的更新、插入和删除语句。仅有两个提供程序,Sql Server和Oracle,曾经实现过此类,并且已知Oracle的此类存在基本问题之外的错误。
如果您使用了两个DbCommand对象,一个用于选择,另一个用于插入,然后通过DbDataReader循环遍历选择DbCommand的输出,您可以轻松检查该列中是否为空,并提供零的默认值给插入DbCommand,因为您知道它是什么。在必要时了解数据库规则并使用它们不违反任何代码组织规则。无论如何,您都必须知道数据库中有什么才能编写这种代码。
如果您使用的是sql server 2005或更高版本,则另一个建议是使用INSERT INTO .. SELECT语句。如果您的SQL足够好,您可以使用CASE子句来制作单个SQL语句。

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

0
一个小问题,看起来很明显,但实际上很棘手。
_sqlCommandBuilder.ConflictOption = ConflictOption.OverwriteChanges;

如果我引用MSDN定义,你可以阅读:
"If no PrimaryKey is defined, all searchable columns are included in the WHERE clause."

我有个朋友,在某些情况下会使用IDENTITY(1, 1)来定义主键,而不是使用Primary Key。
所以我的问题是,你在你的“更新后”的表B中使用了主键吗?



然后....

为了添加信息,SqlAdapter.FillSchema不使用默认值。 这是FillSchema检索到的信息:

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

(引用自MSDN网站

独特的


主键已定义,但您的第二条信息很有用,谢谢 :) 但它没有解决我的问题。 - Rookian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接