|
er(da);
SqlCommandBuilder 类确保指定的数据适配器可成功地用于对特定的数据源进行批处理更新。SqlCommandBuilder 利用了 SelectCommand 对象中定义的某些属性。这些属性是 Connection、CommandTimeout 和 Transaction。只要更改其中的任何属性,您就需要调用命令生成器的 RefreshSchema 方法来更改进一步批处理更新的生成命令的结构。
您可以混合使用命令生成器和自定义命令。如果 InsertCommand 属性在调用命令生成器之前指向一个有效的命令对象,生成器则只会为 DeleteCommand 和 UpdateCommand 生成代码。而非空的 SelectCommand 属性才是命令生成器得以正常工作的关键。
通常,您之所以使用命令生成器,是因为您觉得自己编写 SQL 命令太复杂了。不过,如果您希望查看生成器生成的源代码,则可以调用如 GetInsertCommand、GetUpdateCommand 和 GetDeleteCommand 这样的方法。
命令生成器是一个特定于提供程序的特性。因此,不可能期望所有类型的托管提供程序都支持它。SQL Server 7.0 和更高版本的提供程序以及 OLE DB 提供程序支持命令生成器。
命令生成器有一个很好的特性,它可以检测自动递增的字段,并相应地优化代码。尤其是,只要它有办法识别某些字段是自动递增字段,就会将自动递增字段从 INSERT 语句中提取出来。这个过程可以通过两种方式来实现。例如,您可以手动设置相应的 DataColumn 对象的 AutoIncrement 属性,或者,更好的方法是,使其基于列在数据源(如 SQL Server)中的属性自动进行。要自动继承这样的属性,请确保将数据适配器的 MissingSchemaAction 属性从默认值 Add 改为 AddWithKey。
返回页首
冲突检测
批处理更新机制对并发有着很乐观的看法。每个记录在读取后并不锁定,仍然公开给其他用户用于进行读取和写入。在这种情况下,可能会发生一些潜在的不一致的情形。例如,将某一行从 SELECT 语句传递到您的应用程序之后,但在批处理更新过程真正将更改返回服务器之前,它可能进行了修改,甚至已被删除。
如果您更新服务器上数据的同时,这些数据已经被另外的某个用户修改,则可能会产生数据冲突。为了避免新的数据被覆盖,ADO.NET 命令生成器会生成带有 WHERE 子句的语句,只有当数据源行的当前状态与应用程序以前读取时的状态一致时,WHERE 子句才生效。如果这样的命令未能更新行,ADO.NET 运行时则会引发一个 DBConcurrencyException 类型的异常。
下面的代码片断说明了如何以一种更准确的方法用 ADO.NET 执行批处理更新操作。 try
{
da.Update(dsChanges, "Employees");
}
catch (DBConcurrencyException dbdcex)
{
// resolve the conflict
}
您正在使用的数据适配器的 “更新” 方法对于第一个更新失败的行会引发异常。此时,控制权又回到客户端应用程序,批处理更新过程停止。不过,仍然会执行所有以前提交的更改。这个过程代表了从 ADO 批处理更新模型到 ADO.NET 的另一个转变。
通过 DBConcurrencyException 类的 Row 属性可使用冲突更新中涉及的 DataRow 对象。这个 DataRow 对象包含行的提交值和原始值。它不包含某个给定列当前存储在数据库中的值。此值 - 即 ADO 的 UnderlyingValue 属性 - 只能通过另一个查询命令检索。
解决冲突、并且有可能继续进行批处理更新的方式是严格特定于应用程序的。如果存在您的应用程序需要继续执行更新的情况,您则应该了解一个微妙的、然而却很棘手的问题。想尽办法解决了行上的冲突之后,还必须想出一种方法来接受批处理已成功完成的内存中行的更改。如果您忽略了这个技术细节,对于以前成功更新的第一个行将产生一个新的冲突!这种情况会反复不断地发生,您的应用程序很快就会进入死锁状态。
返回页首
小结
与 ADO 相比,ADO.NET 中的批处理更新功能更强大,具有更高的可访问性。在 ADO 中,批处理更新机制是一种黑盒子,我们几乎不可能深入其内部,也不可能略微改变一下您需要执行的任务。ADO.NET 中的批处理更新更偏向于一种低级的解决方案,它的实现为您进入其内部并控制事件提供了几个切入点。ADO.NET 批处理更新最棘手的部分是冲突解决。作者真心建议您尽可能将更多的时间用于测试、再测试。这种投资可通过命令生成器节省的所有时间来得到回报。
返回页首
对话栏:数据表中的 Null 值
我从数据库提取数据集,一切顺利。然后我尝试将此数据集保存到 XML 文件,仍然很顺利。但将这个 XML 文件读回数据集时,问题出现了。这是因为,所有具有 NULL 值的列不能持久地保存到 XML 中。是否可以利用某种方法,使 NULL 值作为空标记添加到所得到的 XML?
这种行为是设计使然,是随着在 XML 序列化过程中保存几个字节这种最佳的意图引入的。如果这种行为发生在网络上(比如,在 XML Web 服务内),它所带来的优势会非常明显。
也就是说,可以用一个很简单的办法来解决您的问题。这个窍门就是,通过 ISNULL T-SQL 函数提取列。我们不使用以下代码: SELECT MyColumn FROM MyTable
而应该使用: SELECT ISNULL(MyColumn, '''''''') FROM MyTable
在这种情况下,列的任何 NULL 值将自动变成空字符串,并且不会在数据集转换为 XML 的序列化过程中被忽略。非特定值不一定是空字符串。数值列可以使用 0 或任何其他您希望使用的逻辑空值。
上一页 [1] [2] [C语言系列]NET 中C#的switch语句的语法 [操作系统]全面剖析Windows Server 2008开发指南 [系统软件]托拽Explore中的文件到VB.net的窗口 [系统软件]Boost库在XP+Visual C++.net中的安装 [常用软件]新配色面板:Paint.Net3.0RC1官方下载 [常用软件]用内建的“Net Meeting”聊天 [VB.NET程序]Henry的VB.NET之旅(三)—共享成员 [VB.NET程序]Henry的VB.NET之旅(二)—构造与析构 [VB.NET程序]Henry的VB.NET之旅(一)—失踪的窗体 [VB.NET程序]在托盘上显示Balloon Tooltip(VB.NET)
|