DataSet对象有4种典型功能,包括数据 的提取、删除、更新和插入。实际上我们是对DataSet对象的4个属性分别定义相应的SQL语句来完成的。比如,对SelectCommand对象定义 Select语句,对DeleteCommand对象定义Delete语句等。
每次都需要开发人员来设计这些SQL语句是不是很烦琐?有没有很简单的解决方法呢?这就是CommandBuilder对象。
.NET Framework中的每种数据提供者都有自己的CommandBuilder对象,比如,SqlCommandBulder对象就是SQL Server数据库提供者的命名绑定对象。OleDb数据提供者的对象就是OleDbCommandBuilder等。CommandBuilder最大的用处就是组建一个DataAdapter的UpdateCommand, InsertCommand, DeleteCommand这三个Command的CommandText。
CommandBuilder对象使用方法
为了能够自动生成命令,必须设置 SelectCommand 属性,这是最低要求。 由 SelectCommand 属性检索的表架构确定自动生成的 INSERT、UPDATE 和 DELETE 语句的语法。
为了返回构造 INSERT、UPDATE 和 DELETE SQL 命令所需的元数据,DbCommandBuilder 必须执行 SelectCommand。 因此,必须额外经历一次到数据源的过程,这可能会降低性能。若要实现最佳性能,请显式指定命令而不是使用 DbCommandBuilder。SelectCommand 还必须至少返回一个主键或唯一列。 如果不存在任何主键和唯一列,则会生成 InvalidOperation 异常,并且不会生成命令。
当与DataAdapter 关联时,DbCommandBuilder 会自动生成 DataAdapter 的 InsertCommand、UpdateCommand 和 DeleteCommand 属性(如果它们为空引用)。 如果某个属性已存在 Command,则使用现有 Command。
下面是一个使用CommandBuilder的例子:
Dim da As New SqlDataAdapter("select * from tbauthors",conn)
Dim ds As New DataSet()
da.Fill(ds)
ds.Tables(0).Rows(0)("f_name")="First Name"
'如果没有SqlCommandBuilder这一句,那da.Update(ds)就会出错。
Dim cb as new SqlCommandBuilder(da)
da.Update(ds)
什么时候该用Commandbuilder
- Commandbuilder只适合single table,不适合用在复杂的关系上.
- 如果列名称或表名称包含任何特殊字符(如空格、句点、问号或其他非字母数字字符),即使这些字符用中括号分隔,自动命令生成逻辑仍会失败。 支持格式为 catalog.schema.table 的完全限定表名。
- 每次build的时候,它都会连接到数据库,取得相关信息,才能得到update,delete,insert命令,对性能会有影响
- 如果是固定的表、固定的操作可以直接写DataAdapter的update,insert,delete命令。因为表的字段可能很多,工作量大(as mentioned before),VS.NET提供了visual的方法编辑DataAdapter,当你把DataAdapter控件拖到design上的时候,就会出 现设置的向导,减少工作量
- Commandbuilder适合动态的操作,性能会损失
注意事项:
CommandBuilder最主要透过dataadapter的selectcommand从数据源取回表结构后,再利用这个结构视状况产生适当的Insert,Update与Delete语句并建构command对象。SelectCommand必须至少返回一个主键或唯一列。 如果不存在任何主键和唯一列,则会生成 InvalidOperation 异常,并且不会生成命令。通过联接两个或更多个表来创建的数据库视图不会被视为单个数据库表。 在这种情况下,就必须明确指定每个命令而不能使用CommandBuilder。如果selectcommand发生改变,若要正确更新selectcommand取回的表,则必须使用CommandBuilder.RefreshSchema方法。在复杂情况下,不建议使用CommandBuilder,还是老老实实敲代码安全。