C# ADO.NET CommandBuilder、InsertCommand和默认约束

C# ADO.NET CommandBuilder、InsertCommand和默认约束,c#,ado.net,constraints,sqlcommandbuilder,C#,Ado.net,Constraints,Sqlcommandbuilder,我正在将数据从表A复制到表B。 表B有一个可为空的列,该列的默认约束值为0。 通常,我使用以下访问器设置列的值 public object this[string columnName] { get { return DataTable.Rows[CurrentRow][columnName]; } set { DataTable.Rows[CurrentRow][columnName] = value; } } 但是我不将我的列设置为空 插入整行时,不使用默认值。为可为NUL

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

public object this[string columnName]
{
    get { return DataTable.Rows[CurrentRow][columnName]; }
    set { DataTable.Rows[CurrentRow][columnName] = value; }
}
但是我不将我的列设置为空

插入整行时,不使用默认值。为可为NULL的列插入了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能够使用默认约束吗?

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

_sqlCommandBuilder.ConflictOption = ConflictOption.OverwriteChanges;
如果我引用你的话,你可以读到:

"If no PrimaryKey is defined, all searchable columns are included in the WHERE clause."
我的一个朋友,用来在一些凸轮中定义身份(1,1),而不是主键

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



然后

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

AllowDBNull 
AutoIncrement.You must set AutoIncrementStep and AutoIncrementSeed separately.
MaxLength 
ReadOnly 
Unique
(引自)


独特的

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

更新:

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

继续尝试使用CommandBuilder只会给你带来更多的痛苦。它甚至不能在select子句中处理简单的join语句。它还需要一个主键。如果违反了其中任何一条,则无法生成正确的update、insert和delete语句。只有两个提供商,Sql Server和Oracle,曾经实现过这个类,而Oracle的一个已知有一些bug,这些bug在上述基本问题之外从未被修复过

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


如果您使用sql server 2005或更高版本,另一个建议是使用该语句。如果您的sql足够好,您可以使用一个子句生成一条sql语句。

我不想手动创建update、create、delete语句。我希望我理解正确。如果没有,请让我知道:)您可能会认为,当您向表中添加行时,insert语句中只有您设置的列,从而允许正确显示默认值。这在ADODB中起作用,我很惊讶ADO.NET失去了这一功能。主键已定义,但您的第二个信息是有用的,谢谢:)但它并没有解决我的问题。