zoukankan      html  css  js  c++  java
  • 使用ADO.NET2.0提升数据交互性能 DataSet 数据表

    若要异步执行 Command 命令,另一个必需设置的是:数据库连接字符串内要加上 async=true 属性。若连接字符串没有加上该属性,而通过 Command对象实例调用异步执行的方法,则会产生异常(exception)。若 Command 通过连接执行时,重头到尾都是以同步的方式执行,则依照默认 async=false 的方式设置比较节省资源。若某些命令需要同步执行,另一些需要异步执行,则可以考虑使用不同的连接。 

    在介绍范例应用程序前,我们先稍微谈一下 .NET Framework 所提供的公共的异步运行应用程序设计模式,不只是 ADO.NET2.0,在其他访问耗时的程序编写上,也都可以套用这个模式。 

    .NET Framework内置了让应用程序异步运行的功能,让你在编写应用程序时,不会因为某些耗时等待的操作让程序停止响应,操作界面停滞让用户感觉起来好像死机一样。一般会以多线程的方式处理这种需求,但若你不熟悉线程的运行,或是想利用线程池(Thread Pool)的好处,都可以在较为耗时的操作上,采用 .NET Framework 所提供的异步功能。 

    一般来说文件 I/O、网络访问乃至于 Web Services 访问,以及本节所讨论的 DB 访问等都较为耗时,.NET Framework为这一类的类都提供了上述以 Begin~/End~开头的非同步执行方法,而这些方法皆成对出现。当然,也有可能是自己编写的方法其商业逻辑非常复杂,导致调用该方法后,需要等待一段时间来完成,这时还可以通过 .NETFramework 所提供的委托(Delegate)类来创建异步运行。   

    但是实际在我们的应用中,我们不需要获知DB服务器的返回信息时,我们推荐使用委托,尤其是在Web开发中。

    因为在页面线程启动异步数据库访问时,当页面业务执行完毕后仍然无法放开访问数据库的异步线程。这是我们不希望看到的,但是使用委托却可以避免这个麻烦(webservice异步应用中一样如此)。

    四、使用SqlBulkCopy批量装载数据(仅限SqlClient) 

    以往访问 SQL Server 2000 时,若有大量的数据记录需要添加到数据库内,例如从主机系统或是 NCR Teradata、Oracle等数据库系统下载大量数据记录,我们想要将它们快速添加到 SQL Server 2000中,可以有的选择是调用 T-SQL 的 Bulk Insert 语法、通过Linked Server 执行 SELECT INTO 语法或是执行 bcp.exe 工具程序,以及通过 DTS 的 Bulk Insert Task 或启动Transform Data Task 的快速装载(Use Fast Load)设置。   

    但若要通过自行编写的程序完成批次装载,只能以 C/C++ 调用 OLEDB 或 ODBC 的 Bulk API,无法通过 ADO.NET 或 ADO 等对象来执行。 

    ADO.NET 2.0 的 SqlClient 提供了一个新的类称为 SqlBulkCopy,它让 DataSet 内大量的数据或是 DataReader通过数据流(Stream)直接读取大量的记录,可以快速将这些记录添加到目的数据库的数据表中。但要注意的是它并非如我们一般用的 bcp.exe工具程序,可以从某个符号分隔文件读取大量数据,选择性地搭配格式文件(Format File)将记录装载到数据库中,或是将数据库内的数据导出成为一个文件。但由于DataSet 能集成 XML 数据,因此依然可以采用 SqlBulkCopy 类型,轻松地通过 DataSet 将 XML 文件数据大量转入到数据库。    

    可以利用SqlBulkCopy类快速写入大批量数据,针对SQL Server的优化,可以写入DataRow数据,DataTable,DataReader,并且可以映射不同的数据列名。 

    WriteToServer(DataTable)写入数据表   
    WriteToServer(DataRow[])批次写入数据行   
    WriteToServer(DataTable ,DataRowState)按行状态写入数据库表   
    WriteToServer(IDataReader)写入DataReader对象

    下面是个示例:

    using (SqlConnection sqlcon =    
    new SqlConnection("Data Source=192.168.80.242;user id=oa;password=oapassword;

    initial catalog=test"))    
    {    
    sqlcon.Open();    
    using (SqlBulkCopy bcp = new SqlBulkCopy(sqlcon))    
    {    
    bcp.BulkCopyTimeout = 3000;    
    bcp.DestinationTableName = "dbo.Test01";    
    bcp.ColumnMappings.Add("id", "id");    
    bcp.ColumnMappings.Add("name1", "name1");    
    bcp.ColumnMappings.Add("name2", "name2");    
    bcp.ColumnMappings.Add("name3", "name3");    
    //映射到不同名列    
    bcp.ColumnMappings.Add("changedname4", "name4");    
    bcp.WriteToServer(dt);    
    sqlcon.Close();    
    }    


    但是SqlBulkCopy使用时要注意以下几点: 

    1.确认确实需要大容量更新在执行此操作,(几十行的数据请尽量使用别的渠道)。

    2.确认数据一致性,与检查机制,以免遇到主键冲突,数据不符格式等意外。  

    3.SqlBulkCopy操作可能会导致对目标表元数据的更改(例如,禁用约束检查时)。如果出现这种情况,访问大容量插入表的并发快照隔离事务将失败。

    4.SqlBulkCopy将向数据库下大容量更新锁,请注意并发性,以免其他连接因长时间等待而超时。

    五、DataSet的性能提升 

    对于开发人员来说,ADO.NET 2.0最激动人心的变化莫过于.net开发组终于实现了他们许诺多年的事情:确实提升Dataset的性能了。 

    由于1.1版本Dataset令人不敢恭维的性能使得Dataset许多方面被其性能问题而掩盖。 

    现在,在大幅度提升了Dataset的性能后。Dataset终于能日趋完美了。 

    提升是多方面的,被提升的方面包括下面几块: 

    1.索引引擎被大大的提升 

    在对ADO.NET 2.0的Dataset作了相当数目的测试后,微软终于宣布Dataset2.0的数据访问能力获得极大的提高,广泛的数字是增加44倍!!!而且不像1.1中排序的陡峭曲线,2.0中的排序尽量做到了线型递增! 

    真不知道.net小组是以前做的实在太烂了,还是有了新的狠招被发明了。^_^    

    2. 二进序列制化的Dataset 

    Dataset有个好属性是支持序列化,但是有很多人对其提出了批评。不是这些人不喜欢Dataset支持序列化,而是序列化后的Dataset真的是太肥了。大量的  <xs:element name=””,type…占用了大量的空间以至让人难以忍受。

    现在我们只需要设置 RemotingFormat 属性为SerializationFormat.Binary(默认是SerializationFormat.XML),则在序列化时完全采用二进制的数据格式,如此数据较小,因而较有效率。(官方的观点是缩为SerializationFormat.XML的1/4)。 

  • 相关阅读:
    鼠标移动,背景变色
    datatable 删除行
    GridView新增一行,更新所有行實現
    让层垂直居中于浏览器窗口
    extjs学习笔记(转)
    Extjs中的panel
    JDK和JRE的区别(转)
    EXTJS中form添加按钮触发事件
    web.xml详解
    Oracle数据库中的诊断文件(转)
  • 原文地址:https://www.cnblogs.com/pato/p/1827180.html
Copyright © 2011-2022 走看看