当前位置: 首页 > news >正文

常州迅捷网络推广seo优化公司

常州迅捷网络,推广seo优化公司,内容电商平台有哪些,字节跳动小程序开发平台本文转自#xff1a;http://blog.csdn.net/spidertan/archive/2003/12/13/17110.aspx 概述#xff1a; 本文在微软站点资源的基础上加工整理而成#xff0c;意在介绍在你的ADO.NET应用程序中执行和完成性能优化、稳定性和功能性方面提供最佳的解决方案#xff1b;同…本文转自http://blog.csdn.net/spidertan/archive/2003/12/13/17110.aspx        概述     本文在微软站点资源的基础上加工整理而成意在介绍在你的ADO.NET应用程序中执行和完成性能优化、稳定性和功能性方面提供最佳的解决方案同时也包含在ADO.NET中运用已有的数据对象进行开发的最佳实践和帮助你怎样设计ADO.NET应用程序提供建议。     本文包含以下内容     1.NET框架中的data providers     2对照DataSet和DataReader分别介绍他们的最佳用途     3如何使用DataSet、Commands和Connections     4结合XML     5如果你是ADO程序员也不妨看看ADO.NET与ADO的区别和联系     6结合一些FAQ更深一步讨论ADO.NET观点和使用技巧。     介绍     A.NET框架中的data providers         Data providers在应用程序和数据库之间扮演一个桥梁的角色它使得你可以从一个数据库返回查询结果、执行命令以及对数据集的更新等。     B几种data provider的介绍         下面表格中数据表明各种data provider以及最佳适用数据库对象 提供者 描述 SQL Server.NET Data Provider 在.NET框架中使用System.Data.SqlClient命名空间 建议在中间层应用程序中使用SQL Server7.0或以后版本 建议在独立的应用程序中使用MSDE或SQL Server7.0或更高版本 SQL Server6.5或更早版本必须使用OLE DB.NET Data Provider中的OLE DB Provider For SQL Server。 OLE DB.NET Data Provider 在.NET框架中使用System.Data.OleDb命名空间 建议在中间层应用程序中使用SQL Server6.5或以前版本或者任何在.NET框架SDK中指出的支持OLE DB接口清单的OLE DB ProviderOLE DB接口清单将在后面列出 建议在独立的应用程序中使用Access中间层应用程序不建议使用Access 不再支持为ODBC的OLE DB Provider要访问ODBC使用ODBC.NET Data Provider。 ODBC.NET Data Provider 在.NET框架中使用System.Data.Odbc命名空间 提供对使用ODBC驱动连接的数据库的访问 .NET Data Provider For Oracle 在.NET框架中使用System.Data.OracleClient命名空间 提供对Oracle数据库的访问。 Custom.NET Data Provider 提供一套接口让你可以自定义一个Data Provider SQLXML Managed Classes 包含SQLXML Managed Classes的最新版SQLXML3.0使得你可以访问SQL Server2000或以后版本的XML功能性扩展比如执行XML模板文件、执行XPath查询和使用Updategrams或Diffgrams更新数据等在SQLXML 3.0中存储过程和XML模板将会通过SOAP作为一种WEB服务。         表格中提到的OLE DB接口清单在这里把它列出 OLE DB 对象 接口 OLE DB Services IdataInitilize DataSource IDBInitialize IDBCreateSession IDBProperties IPersist IDBInfo* Session ISessionProperties IOpenRowset IDBSchemaRowset* ITransactionLocal* IDBCreateCommand* Command IcommandText ICommandProperties ICommandWithParameters* IAccessor (only required if ICommandWithParameters is supported) ICommandPrepare* MultipleResults ImultipleResults RowSet Irowset IAccessor IColumnsInfo IColumnsRowset* IRowsetInfo (only required if DBTYPE_HCHAPTER is supported) Row IRow* Error IerrorInfo IErrorRecords ISQLErrorInfo*     C连接SQL Server7.0或更高版本         使用SQL Server.NET Data Provider连接SQL Server7.0或更高版本是最好的方式在于它建立与SQL Server的直接连接而中间不需要任何的技术层衔接。如下图一展示了各种访问SQL Server7.0或更高版本的技术比较 图一连接访问SQL Server7.0或更高版本的各种技术比较         以下例子演示怎样创建和打开一个到SQL Server7.0或更高版本数据库的连接 ‘Visual Basic Dim nwindConn As SqlConnection New SqlConnection(Data Sourcelocalhost;Integrated SecuritySSPI; _                                                   Initial Catalognorthwind) nwindConn.Open() ‘C# SqlConnection nwindConn new SqlConnection(Data Sourcelocalhost; Integrated SecuritySSPI; Initial Catalognorthwind); nwindConn.Open();     D连接ODBC数据源         ODBC.NET Data Provider使用System.Data.Odbc命名空间拥有为SQL Server和OLE DB的.NET Data Porvider一样的结构使用ODBC前缀比如OdbcConnetion和标准的ODBC连接字符。下面例子演示怎样创建和打开一个到ODBC数据源的连接 ‘Visual Basic Dim nwindConn As OdbcConnection New OdbcConnection(Driver{SQL Server};Serverlocalhost; _                                                     Trusted_Connectionyes;Databasenorthwind) nwindConn.Open() ‘C# OdbcConnection nwindConn new OdbcConnection(Driver{SQL Server};Serverlocalhost; Trusted_Connectionyes;Databasenorthwind); nwindConn.Open();     E使用DataReaders、DataSets、DataAdapters和DataViews         ADO.NET使用DataSet和DataReader对象读取数据并存储。DataSet就好比是数据库的直系亲属拥有数据库的所有表、顺序和数据库的约束比如表间关系。DataReader则从数据库读取快速的、只进的的和只读的数据流。使用DataSet你将会经常使用DataAdapter或者CommandBuilder与你的数据库打交道同时你也许会使用DataView去排序和过滤数据DataSet还允许你可以创建一个继承于DataSet的子对象来表现数据中的表、行和列。下面图二显示DataSet对象模型 图二DataSet对象模型 下面将要介绍在什么时候使用DataSet或DataReader最恰当同时也将说明如何使用DataAdapter包括CommandBuilder和DataView最优化对数据的访问。     FDataSet和DataReader的比较         在设计你的应用程序时决定究竟使用DataSet还是使用DataReader主要看在你的应用程序中要实现的功能性级别。         使用DataSet可以在你的应用程序中做以下事情         I在多个离散的结果表之间导航             一个DataSet可以包含多个结果表这些结果表是不连续的。你可以分开处理这些表也可以把这些表当作父子关系进行处理。         II操作多个数据源比如从XML文件和电子数据表等不只一个数据库得到的混合数据         下面的例子演示从SQL Server2000的Northwind数据库读取一个customers表的清单和从Access2000的Northwind数据库读取一个orders表的清单然后使用DataRelation在两个表之间建立一个对应关系 ‘Visual Basic Dim custConn As SqlConnection New SqlConnection(Data Sourcelocalhost;Integrated SecuritySSPI; _ Initial Catalognorthwind;) Dim custDA As SqlDataAdapter New SqlDataAdapter(SELECT * FROM Customers, custConn) Dim orderConn As OleDbConnection New OleDbConnection(ProviderMicrosoft.Jet.OLEDB.4.0; _                                                       Data Sourcec:Program FilesMicrosoft Office _                                                       OfficeSamplesnorthwind.mdb;) Dim orderDA As OleDbDataAdapter New OleDbDataAdapter(SELECT * FROM Orders, orderConn) custConn.Open() orderConn.Open() Dim custDS As DataSet New DataSet() custDA.Fill(custDS, Customers) orderDA.Fill(custDS, Orders) custConn.Close() orderConn.Close() Dim custOrderRel As DataRelation custDS.Relations.Add(CustOrders, _                                     custDS.Tables(Customers).Columns(CustomerID), _                                    custDS.Tables(Orders).Columns(CustomerID)) Dim pRow, cRow As DataRow For Each pRow In custDS.Tables(Customers).Rows  Console.WriteLine(pRow(CustomerID).ToString())  For Each cRow In pRow.GetChildRows(custOrderRel)     Console.WriteLine(vbTab cRow(OrderID).ToString())  Next Next ‘C# SqlConnection custConn new SqlConnection(Data Sourcelocalhost;Integrated SecuritySSPI;Initial Catalognorthwind;); SqlDataAdapter custDA new SqlDataAdapter(SELECT * FROM Customers, custConn); OleDbConnection orderConn new OleDbConnection(ProviderMicrosoft.Jet.OLEDB.4.0;                                                 Data Sourcec:Program FilesMicrosoft OfficeOfficeSamplesnorthwind.mdb;); OleDbDataAdapter orderDA new OleDbDataAdapter(SELECT * FROM Orders, orderConn); custConn.Open(); orderConn.Open(); DataSet custDS new DataSet(); custDA.Fill(custDS, Customers); orderDA.Fill(custDS, Orders); custConn.Close(); orderConn.Close(); DataRelation custOrderRel custDS.Relations.Add(CustOrders,                              custDS.Tables[Customers].Columns[CustomerID],                              custDS.Tables[Orders].Columns[CustomerID]); foreach (DataRow pRow in custDS.Tables[Customers].Rows) {  Console.WriteLine(pRow[CustomerID]);    foreach (DataRow cRow in pRow.GetChildRows(custOrderRel))     Console.WriteLine(t cRow[OrderID]); }         III层中交换数据或者使用一个XML WEB服务与DataReader不一样的是DataSet可以被传递给一个远程的客户端             下面的例子演示如何创建一个XML WEB服务其中使用GetCustomers取数据库中customers表数据使用UpdateCustomers更新数据库中数据 1.     ‘Visual Basic 2.     % WebService Language VB Class Sample % 3.     Imports System 4.     Imports System.Data 5.     Imports System.Data.SqlClient 6.     Imports System.Web.Services 7.     WebService(Namespace:http://microsoft.com/webservices/) _ 8.     Public Class Sample 9.       Public nwindConn As SqlConnection New SqlConnection(Data Sourcelocalhost;Integrated SecuritySSPI;Initial Catalognorthwind) 10.   WebMethod( Description : Returns Northwind Customers, EnableSession : False ) _ 11.   Public Function GetCustomers() As DataSet 12.     Dim custDA As SqlDataAdapter New SqlDataAdapter(SELECT CustomerID, CompanyName FROM Customers, nwindConn) 13.     Dim custDS As DataSet New DataSet() 14.     custDA.MissingSchemaAction MissingSchemaAction.AddWithKey 15.     custDA.Fill(custDS, Customers) 16.     GetCustomers custDS 17.   End Function 18.   WebMethod( Description : Updates Northwind Customers, EnableSession : False ) _ 19.   Public Function UpdateCustomers(custDS As DataSet) As DataSet 20.     Dim custDA As SqlDataAdapter New SqlDataAdapter() 21.     custDA.InsertCommand New SqlCommand(INSERT INTO Customers (CustomerID, CompanyName) _                                          Values(CustomerID, CompanyName), nwindConn) 22.     custDA.InsertCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID) 23.     custDA.InsertCommand.Parameters.Add(CompanyName, SqlDbType.NChar, 15, CompanyName) 24.     custDA.UpdateCommand New SqlCommand(UPDATE Customers Set CustomerID CustomerID, _ 25. CompanyName CompanyName WHERE CustomerID OldCustomerID, nwindConn) 26.     custDA.UpdateCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID) 27.     custDA.UpdateCommand.Parameters.Add(CompanyName, SqlDbType.NChar, 15, CompanyName) 28.     Dim myParm As SqlParameter custDA.UpdateCommand.Parameters.Add(OldCustomerID, SqlDbType.NChar, 5, CustomerID) 29.     myParm.SourceVersion DataRowVersion.Original 30.     custDA.DeleteCommand New SqlCommand(DELETE FROM Customers WHERE CustomerID CustomerID, nwindConn) 31.     myParm custDA.DeleteCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID) 32.     myParm.SourceVersion DataRowVersion.Original 33.     custDA.Update(custDS, Customers) 34.     UpdateCustomers custDS 35.   End Function 36. End Class 37.   38. ‘C# 39. % WebService Language C# Class Sample % 40. using System; 41. using System.Data; 42. using System.Data.SqlClient; 43. using System.Web.Services; 44. [WebService(Namespacehttp://microsoft.com/webservices/)] 45. public class Sample 46. { 47.   public SqlConnection nwindConn new SqlConnection(Data Sourcelocalhost;Integrated SecuritySSPI;Initial Catalognorthwind); 48.   [WebMethod( Description Returns Northwind Customers, EnableSession false )] 49.   public DataSet GetCustomers() 50.   { 51.     SqlDataAdapter custDA new SqlDataAdapter(SELECT CustomerID, CompanyName FROM Customers, nwindConn); 52.     DataSet custDS new DataSet(); 53.     custDA.MissingSchemaAction MissingSchemaAction.AddWithKey; 54.     custDA.Fill(custDS, Customers); 55.     return custDS; 56.   } 57.   [WebMethod( Description Updates Northwind Customers, EnableSession false )] 58.   public DataSet UpdateCustomers(DataSet custDS) 59.   { 60.     SqlDataAdapter custDA new SqlDataAdapter(); 61.     custDA.InsertCommand new SqlCommand(INSERT INTO Customers (CustomerID, CompanyName)                                           Values(CustomerID, CompanyName), nwindConn); 62.     custDA.InsertCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID); 63.     custDA.InsertCommand.Parameters.Add(CompanyName, SqlDbType.NChar, 15, CompanyName); 64.     custDA.UpdateCommand new SqlCommand(UPDATE Customers Set CustomerID CustomerID, CompanyName CompanyName WHERE CustomerID OldCustomerID, nwindConn); 65.     custDA.UpdateCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID); 66.     custDA.UpdateCommand.Parameters.Add(CompanyName, SqlDbType.NChar, 15, CompanyName); 67.     SqlParameter myParm custDA.UpdateCommand.Parameters.Add(OldCustomerID, SqlDbType.NChar, 5, CustomerID); 68.     myParm.SourceVersion DataRowVersion.Original; 69.     custDA.DeleteCommand new SqlCommand(DELETE FROM Customers WHERE CustomerID CustomerID, nwindConn); 70.     myParm custDA.DeleteCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID); 71.     myParm.SourceVersion DataRowVersion.Original; 72.     custDA.Update(custDS, Customers); 73.     return custDS; 74.   } }         IV数据的再使用比如排序、搜索或过滤数据         V执行每行的大容量数据处理处理DataReader挂起的连接服务已不再需要、影响性能的每一行         VI使用诸如XSLT转换或者XPath查询等XML操作的多重数据。             下面的例子介绍如何使用XmlDataDocument同步DataSet数据和如何使用XSLT样式文件在HTML文件中包含DataSet数据首先是XSLT样式文件 xsl:stylesheet xmlns:xslhttp://www.w3.org/1999/XSL/Transform version1.0 xsl:template matchCustomerOrders  HTML  STYLE  BODY {font-family:verdana;font-size:9pt}  TD   {font-size:8pt}  /STYLE     BODY     TABLE BORDER1       xsl:apply-templates selectCustomers/     /TABLE     /BODY  /HTML /xsl:template xsl:template matchCustomers     TRTD       xsl:value-of selectContactName/, xsl:value-of selectPhone/BR/     /TD/TR       xsl:apply-templates selectOrders/ /xsl:template xsl:template matchOrders  TABLE BORDER1     TRTD valigntopBOrder:/B/TDTD valigntopxsl:value-of selectOrderID//TD/TR     TRTD valigntopBDate:/B/TDTD valigntopxsl:value-of selectOrderDate//TD/TR     TRTD valigntopBShip To:/B/TD         TD valigntopxsl:value-of selectShipName/BR/         xsl:value-of selectShipAddress/BR/         xsl:value-of selectShipCity/, xsl:value-of selectShipRegion/ xsl:value-of selectShipPostalCode/BR/         xsl:value-of selectShipCountry//TD/TR  /TABLE /xsl:template /xsl:stylesheet             接着下面的代码演示如何填充DataSet的数据和运用XSLT样式 ‘Visual Basic Imports System Imports System.Data Imports System.Data.SqlClient Imports System.Xml Imports System.Xml.Xsl Public Class Sample  Public Shared Sub Main()     Dim nwindConn As SqlConnection New SqlConnection(Data Sourcelocalhost;Initial Catalognorthwind;Integrated SecuritySSPI)     nwindConn.Open()     Dim myDataSet As DataSet New DataSet(CustomerOrders)     Dim custDA As SqlDataAdapter New SqlDataAdapter(SELECT * FROM Customers, nwindConn)     custDA.Fill(myDataSet, Customers)     Dim ordersDA As SqlDataAdapter New SqlDataAdapter(SELECT * FROM Orders, nwindConn)     ordersDA.Fill(myDataSet, Orders)     nwindConn.Close()     myDataSet.Relations.Add(CustOrders,_                            myDataSet.Tables(Customers).Columns(CustomerID),_                            myDataSet.Tables(Orders).Columns(CustomerID)).Nested true     Dim xmlDoc As XmlDataDocument New XmlDataDocument(myDataSet)     Dim xslTran As XslTransform New XslTransform     xslTran.Load(transform.xsl)     Dim writer As XmlTextWriter New XmlTextWriter(xslt_output.html, System.Text.Encoding.UTF8)     xslTran.Transform(xmlDoc, Nothing, writer)     writer.Close()  End Sub End Class ‘C# using System; using System.Data; using System.Data.SqlClient; using System.Xml; using System.Xml.Xsl; public class Sample {  public static void Main()  {     SqlConnection nwindConn new SqlConnection(Data Sourcelocalhost;Initial Catalognorthwind;Integrated SecuritySSPI;);     nwindConn.Open();     DataSet custDS new DataSet(CustomerDataSet);     SqlDataAdapter custDA new SqlDataAdapter(SELECT * FROM Customers, nwindConn);     custDA.Fill(custDS, Customers);     SqlDataAdapter ordersDA new SqlDataAdapter(SELECT * FROM Orders, nwindConn);     ordersDA.Fill(custDS, Orders);     nwindConn.Close();     custDS.Relations.Add(CustOrders,                          custDS.Tables[Customers].Columns[CustomerID],                          custDS.Tables[Orders].Columns[CustomerID]).Nested true;     XmlDataDocument xmlDoc new XmlDataDocument(custDS);     XslTransform xslTran new XslTransform();     xslTran.Load(transform.xsl);     XmlTextWriter writer new XmlTextWriter(xslt_output.html, System.Text.Encoding.UTF8);     xslTran.Transform(xmlDoc, null, writer);     writer.Close();  } }         使用DataReader可以在你的应用程序中做以下事情         I不需要缓存数据         II处理太大而不能存储的数据         III需要以只进、只读和快速方式一次性访问数据的。     G使用一个自定义的强有力的DataSet类型的好处         通过创建一个继承于DataSet的子对象你可以在运行期间执行类型检查和声明。当你有了一个确定的计划或者为你的DataSet有相关的结构你就可以创建一个用行和列表述一个对象的DataSet。比如你表露一个消费者对象的名字属性来取代表露消费者表的一行中的名字列。有关此节详细信息请参考微软站点上的文章Working with a Typed DataSet     H在自定义的DataSet中处理无效数据         通过XSD语言检查你的DataSet确保你的DataSet适当地处理无效引用。nullValue注释使你把BBNull替换成别的字符String.Empty或者保留无效引用抛出错误提示提示将取决于你应用程序的上下文默认情况是引用了无效字符。     I在DataSet中刷新数据         如果你要从数据库刷新你的DataSet使用DataAdapter.Fill如果你的DataTable拥有主键DataAdapter.Fill将根据主键匹配新的行同时从数据库取值运用到已存在的行。除非已刷新行在再次刷新前被修改否者它的RowState将会被设置为UnChanged。注意的是如果DataTable没有设置主键你的DataSet有可能出现重复的值。如果你想从数据库刷新一个表并保留任何表中行的更改那么你就要首先填充一个新表然后利用preserveChanges等于true来合并那个DataTable到你的DataSet中去。     J在DataSet中搜索数据         当你在一个DataSet中查询特殊标准的行时利用索引查询将会增加你的查询性能。当你给一个DataTable设计主键时索引同时也创建了。当你为一个DataTable创建DataView时索引也同时创建了。以下是使用索引查询的一些情况         I如果查询与DataTable中标识主键的列顺序相反使用DataTable.Rows.Find代替DataTable.Select         II如果查询包括无主键的列你可以使用DataView为数据的多重查询改善性能。当你在DataView中使用排序时查询的同时就会创建一个索引。DataView使用Find和FindRows方法查询DataTable中的数据         IV假如你不需要表的排序视图你也可以利用DataView为DataTable创建一个索引查询。注意的是这仅仅在你执行多重查询时才有优势如果你只是执行一个简单查询使用此方法将会降低你的查询效率。     KDataView的结构         前面也讲过在给DataTable创建DataView和Sort、RowFilter或者RowStateFilter属性发生更改的同时潜在的也给DataTable创建了索引。创建DataView对象时如果Sort、RowFilter和RowStateFilter属性也同时指定那么索引将只创建一次如果创建一个空的DataView那么索引至少被创建两次。     L页面调度         ADO.NET使你可以很清楚地控制从你的数据库返回什么样的数据和有多少数据存储到一个DataSet。以下没有单一的介绍调度一个查询结果但是当你设计你的应用程序时应该考虑到以下情况         I避免在使用DataAdapter.Fill时在startRecord和maxRecords值上溢出。         II解决这类问题的办法是使用WHERE语句、ORDER BY语句和TOP断言。         III还有一种解决办法是使用TOP断言和嵌套的SELECT声明。比如如下代码      SELECT TOP 10 * FROM (SELECT TOP 30 * FROM Customers ORDER BY Id ASC) AS Table1 ORDER BY Id DESC IV如果你的日期不是经常改变你可以使用DataSet的存储功能改善执行性能比如你可以存储相当10页的数据到你的DataSet然后当用户访问超过在存储区的FirstPage和LastPage时才查询数据库以获得新的数据。     M有计划地填充DataSet         当使用数据填充DataSet时DataAdapter.Fill方法使用DataSet已有的计划和SelectCommand返回的数据对DataSet进行填充。如果DataSet中没有与之对应的表将会失败Fill创建一个表默认情况下Fill仅仅定义列和列的类型。你可以通过设置DataAdapter的MissingSchemaAction属性重载默认的Fill方法。举例要使Fill方法创建表时总是包含主键信息、唯一约束、列属性、是否允许空值、列的最大长度、只读列和自动增量列指定DataAdapter.MissingSchemaAction为MissingSchemaAction.AddWithKey。作为选择你也可以在调用DataAdapter.Fill之前调用DataAdpater.FillSchema来保证填充DataSet时计划到位。调用FillSchema会给数据库增加额外的负担来输出Schema信息所以最好的建议是指定DataSet的计划或者在调用Fill之前设置DataAdapter的MissingSchemaAction。     N使用CommandBuilder         CommandBuilder自动地生成基于DataAdapter的SelectCommand的DataAdapter的InsertCommand、UpdateCommand和DeleteCommand属性。提供SelectCommand执行一个简单的SELECT以下信息介绍使用CommandBuilder的最佳处理。         I在设计阶段不要使用CommandBuilder否者产生DataAdapter Command属性的进程将会受到干扰。如果你预先知道你的UPDATE、INSERT和DELETE声明的内容你应该清楚地指定。一个最好的设计方案是为你的UPDATE、INSERT和DELETE创建存储过程并在DataAdapter的Command属性中设置和使用它们。         IICommandBuilder使用SelectCommand决定其他Command属性的值。如果DataAdapter的SelectCommand本身发生变化应该使用RefreshSchema去刷新Command的属性。         III只要DataAdapter的Command属性为空CommandBuilder就仅仅创建一个Command即使你明确地指定Command的属性值CommandBuilder也不会重写所以如果你想创建一个Command并保留以前的属性设置那么就把Command的属性设置为null。     OSQL的批声明和处理         很多的数据库都支持在一条命令中使用综合查询或批处理或多条子命令。比如SQL Server中使用“”。在一条命令中使用综合的多重命令可以有效地减少与数据库之间交互的次数并在你的应用程序中提高效率。比如在你的应用程序中使用批处理完成所有的删除delete任务等等。         使用批处理确实提高了效率但同时也在你的应用程序中管理更新DataSet数据时增加了复杂性。要使得复杂性变简单化你就要在你的DataSet中为每个DataTable创建一个DataAdapter。     P使用多个表填充一个DataSet         如果你是用批处理从多个表返回数据并把这些数据填充到一个DataSetfill方法将会使用第一个表的表名命名第一个表以后的表命名将会采用在第一个表的表名基础上加上一个递增的数字。举例下面的代码将逐步说明fill方法的工作原理         ‘Visual Basic         Dim da As SqlDataAdapter New SqlDataAdapter(“select * from customers;select * from orders;”,myConnection)         Dim ds As DataSet New DataSet()         da.fill(ds,”customers”)         ‘C#         SqlDataAdapter da new SqlDataAdapter(“select * from customers;select * from orders;”,myConnection);         DataSet ds new DataSet();         da.fill(ds,”customers”);         如上面代码所示customers表数据将会存放在一个命名为customers的DataTable中而orders表数据将会放在一个命名为customers1的DataTable中。当然你也可以在数据填充结束后很容易地修改customers1表属性TableName为orders。然而在以后的数据填充时只会影响customers表中数据而orders表将会忽略并同时创建一个新的命名为customers1的表。要解决这个问题你就要在customers1和orders之间建立一个DataTableMapping映射。其他表也如此。举例说明         ‘Visual Basic Dim da As SqlDataAdapter New SqlDataAdapter(SELECT * FROM Customers; SELECT * FROM Orders;, myConnection) da.TableMappings.Add(Customers1, Orders) Dim ds As DataSet New DataSet() da.Fill(ds, Customers) ‘C# SqlDataAdapter da new SqlDataAdapter(SELECT * FROM Customers; SELECT * FROM Orders;, myConnection); da.TableMappings.Add(Customers1, Orders); DataSet ds new DataSet(); da.Fill(ds, Customers);     Q使用DataReader         下面是使用DataReader的一些技巧和一些问题的回答         I在使用相关Command访问任何输出参数之前必须关闭DataReader         II在读取数据结束后应当关闭DataReader。如果你的Connection仅仅是用来返回DataReader那么在关闭DataReader之后你也应该立即关闭它。另外一个关闭Connection的方法是传递CommandBehavior.CloseConnection给ExecuteReader方法。此方法在你从一个方法中返回DataReader并且对这个DataReader没有关闭控制权或者关联的连接时使用时非常有用的。         IIIDataReader是为已连接的数据存取设计         IV使用GetString、GetInt32等返回特殊数据类型数据         V一个连接只允许使用一个DataReader。在ADO中如果你只创建一个连接并使用两个recordsets一个只读游标和一个只进游标但实际上ADO已经为你创建了一个隐式的连接并在不用的时候隐式地关闭它。ADO.NET中是不行的你必须为每个DataReader创建一个Connection这也是为了让你在使用Connection时给予更多的控制信息。         VI默认下DataReader每次读取时把行中所有的数据装载到内存中。并允许你随机存取当前行中数据。如果随即存取没有必要没有必要把所有数据都装载到内存并想提高执行效率给ExecuteReader方法传递CommandBehavior.SequentialAccess这样就会改变DataReader的默认动作为仅仅装载请求的数据到内存。注意的是这种方法要求你顺序地存取行中列数据一旦你略过某一列以后你将再不会读取到该列的数据。         VII如果当你在完成从一个DataReader读取数据后仍然还有大量未读不需要的数据这就要在调用DataReader的Close命令之前调用Cancel命令。调用DataReader的Close命令会导致把不需要的数据装载进来并在关闭游标之前清空数据。而调用Cancel命令就会丢弃这部分数据从而DataReader在关闭之前就不会读取它们。如果你正在从你的命令返回输出参数调用Cancel命令同样会丢弃它们。如果你需要读取任何输出参数你就不要使用Cancel而直接使用Close。     RBLOBs对象         当你使用DataReader读取二进制数据时你应该传递CommandBehavior.SequentialAccess给ExecuteReader方法调用。因为DataReader的默认情况是每次读取数据时把每行中所有的数据都存储到内存而二进制数据又非常的大结果就会使大量的内存空间被一个单一的BLOB占用。SequentialAccess使得你的DataReader默认行为为仅读取需要的数据。然后你就可以使用GetBytes或者GetChars决定一次读取多少数据。         记住的是使用SequentialAccess后你不能次序颠倒地访问DataReader中不同的字段。就是说如果你的查询返回三列其中第三列是BLOB数据类型如果你想访问第三列数据那么你就必须先访问第一列然后是第二列再然后才是第三列的BLOB数据。这是因为此时返回的数据是有序的而且一旦你跳过某一列再回过头来读取这一列是不行的。     S使用命令         ADO.NET提供了执行命令的几种不同方法同时也提供了优化执行命令的几种不同参数。下面将要介绍的是选择最佳执行命令的技巧和改善一个可执行命令的性能。         IOleDbCommand最佳实践         .NET 框架中各种数据提供者之间的执行命令标准几乎是一样的。但是也有不同下面是执行OleDbCommand的一些技巧             ①使用CommandType.Text调用存储过程使用CommandType.StoredProcedure生成             ②确定设置OleDbParameter的类型、大小如果要求和精度如果是数字或者小数注意的是如果你不明确设置OleDbParameterOleDbCommand将会为你的执行命令重新生成OleDbParameter。         IISqlCommand最佳实践             使用SqlCommand快速执行存储过程如果你要调用一个存储过程指定SqlCommand的CommandType为存储过程的CommandType。这样在执行命令时就会提交此命令是调用存储过程从而达到快速执行。         III使用已准备的方法             Command.Prepare方法优化你的参数化执行命令。Prepare结构为多重调用最优化指定命令。要使用Prepare你首先得理解你的数据库是怎样相应Prepare调用。SQL Server 2000中Command已经被隐式优化和Prepare不是必须的在SQL Server7.0或其它数据库中使用Prepare是有效的。         IV明确地指定计划和元数据             ADO.NET中的很多对象都要推断元数据信息只要用户不指定它举例如下             ①如果在DataSet中不存在DataAdapter.Fill方法就会创建表和列信息             ②CommandBuilder为独立表的Select命令生成DataAdpater命令参数             ③CommandBuilder.DeriveParameters组装一个命令对象的参数信息         如果什么时候都使用上面讲的方法可能会降低执行性能。推荐在设计阶段和广告段应用程序中使用。可能的情况下一般都要指定计划和元数据。这些包括指定DataSet的表和列、指定DataAdapter的Command属性和指定Command的参数信息。         VExecuteScalar和ExecuteNonQuery             如果你想只返回一个简单值比如Count(*)、Sum(Price)或者Avg(Quantity)你可以使用ExecuteScalar它帮助你一步到位得到你想要的值从而避免使用DataReader的两步计算ExecuteReaderGetValue             当你不想返回行信息比如修改数据INSERT、UPDATE、DELETE或者仅需要输出参数或者返回值使用ExecuteNonQuery它去掉不必要的处理创建一个空的DataReader。         VI空值检查             如果在你的表中某列允许空值你可以使用Where语句进行空值检查下面举例说明         select * from customers where ((LastNameLastName) or (LastName IS NULL and LastName IS NULL))             上面语句检查了列是否为空和参数是否为空。         VII传递null参数值             当你在命令中传递null参数值给数据库时你不能使用nullNothing在vb中应该使用DBNull.Value。举例         ‘vb         Dim param As SqlParameter New SqlParameter(“Name”,SqlDbType.NVarChar,20)         param.Value DBNull.Value         ‘C#         SqlParameter param new SqlParameter(“Name”,SqlDbType.NVarChar,20);         param.Value DBNull.Value;         VIII使用事务处理             ADO.NET中的事务处理模型已经改变在ADO中一旦StartTransaction被调用任何事务下的更新都被认为是事务的一部分。然而在ADO.NET中当Connection.BeginTransaction被调用返回一个命令关联的事务对象事务属性是由命令的事务属性指定的。这样保证让你在一个Connection中执行多个事务。如果命令的Command.Transaction属性与开始的事务不一致命令就不会完成并抛出错误。         IX使用Connections             高效率的应用程序应该使用最少的时间与数据库建立连接比如使用Connection Pooling等。下面将介绍如何使用ADO.NET建立高效率应用的一些数据库方面的技巧。         ①Connection Pooling             在SQL Server、OLE DB和.NET框架结构中的Data Provider中都提供了隐式的连接池连接支持。你可以在ConnectionString中指定不同的参数值控制连接池的行为。比如下面的例子使OLE DB的连接池无效并自动地进行事务处理         ProviderSQLOLEDB;OLE DB Services-4;Data Sourcelocalhost;Integrated SecuritySSPI;             在SQL Server.NET Data Provider中提供了以下参数设置控制连接池的行为Connection Lifttime、Connection Reset、Enlist、Max Pool Size、Min Pool Size和Pooling。         ②使用DataAdapter最优化连接             使用DataAdpater的Fill和Update方法时会自动地打开相应的连接。如果Fill或者Update打开一个连接在它操作完成后它会关闭此连接。最好的执行方式是在你需要的时候才建立连接。同时减少多个操作时打开和关闭连接的次数。             推荐你在仅仅执行一个Fill或者Update时允许Fill或者Update方法隐式地打开和关闭连接如果你要执行多个Fill或者Update建议你显式地建立连接、执行Fill或者Update操作然后显式地关闭连接。             额外地在我们执行事务处理时在开始事务之前应该显式地建立连接并在事务结束后显式地关闭连接。举例 ‘Visual Basic Public Sub RunSqlTransaction(da As SqlDataAdapter, myConnection As SqlConnection, ds As DataSet)  myConnection.Open()  Dim myTrans As SqlTransaction myConnection.BeginTransaction()  myCommand.Transaction myTrans  Try     da.Update(ds)     myTrans.Commit()     Console.WriteLine(Update successful.)  Catch e As Exception     Try       myTrans.Rollback()     Catch ex As SqlException       If Not myTrans.Connection Is Nothing Then         Console.WriteLine(An exception of type ex.GetType().ToString() _                           was encountered while attempting to roll back the transaction.)       End If     End Try     Console.WriteLine(An exception of type e.GetType().ToString() was encountered.)     Console.WriteLine(Update failed.)  End Try  myConnection.Close() End Sub ‘C# public void RunSqlTransaction(SqlDataAdapter da, SqlConnection myConnection, DataSet ds) {  myConnection.Open();  SqlTransaction myTrans myConnection.BeginTransaction();  myCommand.Transaction myTrans;  try  {     da.Update(ds);     myCommand.Transaction.Commit();     Console.WriteLine(Update successful.);  }  catch(Exception e)  {     try     {       myTrans.Rollback();     }     catch (SqlException ex)     {       if (myTrans.Connection ! null)       {         Console.WriteLine(An exception of type ex.GetType()                           was encountered while attempting to roll back the transaction.);       }     }     Console.WriteLine(e.ToString());     Console.WriteLine(Update failed.);  }  myConnection.Close(); }         X总是关闭Connections和DataReaders             在你使用完Connection或者DataReader对象后你应该明确地关闭它们。系统中的碎片整理程序只是在最后需要的时候才进行整理而一些很耗资源的连接还得由你自己来释放。同时如果你不明确地关闭连接此连接就有可能不返回连接池除非连接池的Max Pool Size已经达到并且此连接还仍然有效。             注意在你的类的Finalize方法中不要使用Close或者Dispose运用到一个Connection或者一个DataReader或者任何被管理对象上。在一个Finalizer中仅仅释放你的类直接拥有的无法管理的资源。如果你的类不拥有任何无法管理的资源就不要在你的类使用Finalize方法。         XI在C#中使用Using声明             在C#中一个非常便利的保证关闭你使用过的Connection和DataReader对象的方法是使用Using声明。当对象超出了它的使用范围Using声明就会自动地释放该对象。举例 ‘C# string connString Data Sourcelocalhost;Integrated SecuritySSPI;Initial CatalogNorthwind;; using (SqlConnection conn new SqlConnection(connString)) {  SqlCommand cmd conn.CreateCommand();  cmd.CommandText SELECT CustomerId, CompanyName FROM Customers;    conn.Open();  using (SqlDataReader dr cmd.ExecuteReader())  {     while (dr.Read())       Console.WriteLine({0}t{1}, dr.GetString(0), dr.GetString(1));  } }             Using声明在Visual Basic.Net中不可用。         XII避免访问OleDbConnection.State属性             如果你需要经常检查State属性最好在OleDbConnection上监听StateChange事件。下面的代码演示当OleDbConnection.State发生变化时使用StateChange向控制台发送一条消息 ‘Visual Basic AddHandler nwindConn.StateChange, New StateChangeEventHandler(AddressOf OnStateChange) Protected Shared Sub OnStateChange(sender As Object, args As StateChangeEventArgs)  Console.WriteLine(The current Connection state has changed from {0} to {1}., _                     args.OriginalState, args.CurrentState) End Sub ‘C# nwindConn.StateChange  new StateChangeEventHandler(OnStateChange); protected static void OnStateChange(object sender, StateChangeEventArgs args) {  Console.WriteLine(The current Connection state has changed from {0} to {1}.,                     args.OriginalState, args.CurrentState); }     T与XML结合         ADO.NET在DataSet中提供对XML的广泛支持同时在SQL Server2000或以后版本中的XML功能性扩展也能在ADO.NET中得到充分运用。你可以使用SQLXML访问在SQL Server2000和以后版本中提供的XML功能性扩展。下面是使用XML和ADO.NET的一些技巧信息。         IDataSet和XML         DataSet和XML的完美整合可以使你完成以下事情             ①从XSD计划中载入一个DataSet的计划或相关结构             下面的例子说明一个XSD文件的结构其中MyDataSet就是我们的DataSet元素它下面包含一个customers复合类型元素有了它我们就可以映射创建一个这样的表Customers CustomerIDCompanyNamePhone同时也定义我们的DataSet的计划或者结构 xs:schema idSomeID              xmlns              xmlns:xshttp://www.w3.org/2001/XMLSchema              xmlns:msdataurn:schemas-microsoft-com:xml-msdata     xs:element nameMyDataSet msdata:IsDataSettrue       xs:complexType         xs:choice maxOccursunbounded           xs:element namecustomers             xs:complexType               xs:sequence                 xs:element nameCustomerID typexs:integer                              minOccurs0 /                 xs:element nameCompanyName typexs:string                              minOccurs0 /                 xs:element namePhone typexs:string /               /xs:sequence             /xs:complexType            /xs:element         /xs:choice       /xs:complexType     /xs:element  /xs:schema             ②从XML文件中载入一个DataSet的内容             要从XML文件填充DataSet的内容请使用DataSet对象的ReadXml方法。下面的例子说明如何从一个XML文件读取数据到一个DataSet ‘Visual Basic Dim myDS As DataSet New DataSet myDS.ReadXml(input.xml, XmlReadMode.ReadSchema) ‘C# DataSet myDS new DataSet(); myDS.ReadXml(input.xml, XmlReadMode.ReadSchema);             ③当没有提供计划时从一个XML文件的内容中推断一个DataSet的计划             要从一个XML文件载入DataSet的计划信息你可以使用DataSet对象的ReadXmlSchema方法。如果没有提供计划你还可以使用InferXmlSchema从XML文件推断DataSet的计划下面的例子介绍如何通过InferXmlSchema从一个XML文件推断出DataSet的计划 ‘Visual Basic Dim myDS As DataSet New DataSet myDS.InferXmlSchema(input_od.xml, New String[] {urn:schemas-microsoft-com:officedata}) ‘C# DataSet myDS new DataSet(); myDS.InferXmlSchema(input_od.xml, new string[] urn:schemas-microsoft-com:officedata);             ④象XSD格式计划一样写一个DataSet的计划             下面的例子展示如何通过ReadXmlSchema从一个XSD文件载入DataSet的计划 ‘Visual Basic Dim myDS As DataSet New DataSet myDS.ReadXmlSchema(schema.xsd) ‘C# DataSet myDS new DataSet(); myDS.ReadXmlSchema(schema.xsd);             ⑤象XML格式文件一样读写一个DataSet的内容。             利用DiffGrams从DataSet中读写内容下面的例子显示在提交更改之前更新表中一行数据的结果其中CustomerID为ALFKI的那一行数据被修改但是还没有更新 diffgr:diffgram xmlns:msdataurn:schemas-microsoft-com:xml-msdata xmlns:diffgrurn:schemas-microsoft-com:xml-diffgram-v1  CustomerDataSet     Customers diffgr:idCustomers1 msdata:rowOrder0 diffgr:hasChangesmodified       CustomerIDALFKI/CustomerID       CompanyNameNew Company/CompanyName     /Customers     Customers diffgr:idCustomers2 msdata:rowOrder1 diffgram:hasErrorstrue       CustomerIDANATR/CustomerID       CompanyNameAna Trujillo Emparedados y helados/CompanyName     /Customers     Customers diffgr:idCustomers3 msdata:rowOrder2       CustomerIDANTON/CustomerID       CompanyNameAntonio Moreno Taquerí­a/CompanyName     /Customers     Customers diffgr:idCustomers4 msdata:rowOrder3       CustomerIDAROUT/CustomerID       CompanyNameAround the Horn/CompanyName     /Customers  /CustomerDataSet  diffgr:before     Customers diffgr:idCustomers1 msdata:rowOrder0       CustomerIDALFKI/CustomerID       CompanyNameAlfreds Futterkiste/CompanyName     /Customers  /diffgr:before  diffgr:errors     Customers diffgr:idCustomers2 diffgr:ErrorAn optimistic concurrency violation has occurred for this row./  /diffgr:errors /diffgr:diffgram         注意你可以在你的DataSet中使用XPath查询和XSLT转换来同步运用XML的功能性或者提供一个相关的视图或者创建一个XML文档数据的一个副本。         II计划接口             当你从一个XML文件载入一个DataSet时你可以从XSD计划载入DataSet的计划或者你可以在载入数据之前预先确定表和列。如果这里没有XSD计划或者你又不知道那个表和列是XML文件内容确定的那么你可以使用基于XML文档结构推断计划。             计划接口是一个很有用的移植工具但是它应该限制在设计阶段的应用程序中仅仅因为以下几点             ①推断计划将会提出额外的处理从而影响应用程序性能的提高             ②所有的列将会是一个数据类型string             ③推断过程具有不确定性。那就是说它是基于XML文件的而不是基于有意的计划。         IIISQL SERVER 的FOR XML查询             如果你想返回如SQL SERVER的FOR XML查询结果你可以用SQL Server.NET Data Provider直接使用SqlCommand.ExecuteXmlReader方法创建一个XmlReader。         IVSQLXML管理类             在.NET框架中SQLXML管理类使用Microsoft.Data.SqlXml命名空间。它使得你可以执行Xpath查询和XML模板文件如同运用XSLT转换数据一样。最新版本是SQLXML3.0。     U更多有用技巧         I避免自动增量值冲突             像大多数数据库一样DataSet让你在增加新的数据时标识为自动增量的列自动填充增量值。使用自动增量时应当避免本地DataSet的增量值与数据库的增量值相冲突。要避免这种情况推荐在数据库和DataSet同时使用自动增量时在你的DataSet中创建AutoIncrementStep为-1和AutoIncrementSeed为0的自动增量列同时保证你的数据库中的列从1开始正方向递增。这样就保证一个负方向的增量不会与一个正方向的增量相冲突。另外一种方法是使用Guid代替自动增量。在DataSet中产生的Guid永远不会与数据库中产生的Guid一样。如果你的自动增量列只是简单地用作唯一值并且不表示任何含义建议你使用Guids代替自动增量。它们是唯一的并避免使用自动增量产生的额外工作。         II处理乐观并发错误             因为DataSet与数据库是分离的所以你应该在你的应用程序中避免当多个客户更新数据库数据时发生冲突。这里有几种处理乐观并发错误的解决方案。一是在你的表中增加一个时间戳列。二是校验一行中所有列的数据是否与你在SQL声明中使用Where子句找到的数据静态匹配。下面的例子说明如何使用where条件处理乐观并发错误 ‘Visual Basic  Dim nwindConn As SqlConnection New SqlConnection(Data Sourcelocalhost;Integrated SecuritySSPI;Initial Catalognorthwind)  Dim custDA As SqlDataAdapter New SqlDataAdapter(SELECT CustomerID, CompanyName FROM Customers ORDER BY CustomerID, nwindConn)   The Update command checks for optimistic concurrency violations in the WHERE clause.  custDA.UpdateCommand New SqlCommand(UPDATE Customers (CustomerID, CompanyName) VALUES(CustomerID, CompanyName) _                                         WHERE CustomerID oldCustomerID AND CompanyName oldCompanyName, nwindConn)  custDA.UpdateCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID)  custDA.UpdateCommand.Parameters.Add(CompanyName, SqlDbType.NVarChar, 30, CompanyName)   Pass the original values to the WHERE clause parameters.  Dim myParm As SqlParameter  myParm custDA.UpdateCommand.Parameters.Add(oldCustomerID, SqlDbType.NChar, 5, CustomerID)  myParm.SourceVersion DataRowVersion.Original  myParm custDA.UpdateCommand.Parameters.Add(oldCompanyName, SqlDbType.NVarChar, 30, CompanyName)  myParm.SourceVersion DataRowVersion.Original   Add the RowUpdated event handler.  AddHandler custDA.RowUpdated, New SqlRowUpdatedEventHandler(AddressOf OnRowUpdated)  Dim custDS As DataSet New DataSet()  custDA.Fill(custDS, Customers)   Modify the DataSet contents.  custDA.Update(custDS, Customers)  Dim myRow As DataRow  For Each myRow In custDS.Tables(Customers).Rows     If myRow.HasErrors Then Console.WriteLine(myRow(0) vbCrLf myRow.RowError)  Next Private Shared Sub OnRowUpdated(sender As object, args As SqlRowUpdatedEventArgs)  If args.RecordsAffected 0     args.Row.RowError Optimistic Concurrency Violation Encountered     args.Status UpdateStatus.SkipCurrentRow  End If End Sub ‘C#  SqlConnection nwindConn new SqlConnection(Data Sourcelocalhost;Integrated SecuritySSPI;Initial Catalognorthwind);  SqlDataAdapter custDA new SqlDataAdapter(SELECT CustomerID, CompanyName FROM Customers ORDER BY CustomerID, nwindConn);  // The Update command checks for optimistic concurrency violations in the WHERE clause.  custDA.UpdateCommand new SqlCommand(UPDATE Customers (CustomerID, CompanyName) VALUES(CustomerID, CompanyName)                                         WHERE CustomerID oldCustomerID AND CompanyName oldCompanyName, nwindConn);  custDA.UpdateCommand.Parameters.Add(CustomerID, SqlDbType.NChar, 5, CustomerID);  custDA.UpdateCommand.Parameters.Add(CompanyName, SqlDbType.NVarChar, 30, CompanyName);  // Pass the original values to the WHERE clause parameters.  SqlParameter myParm;  myParm custDA.UpdateCommand.Parameters.Add(oldCustomerID, SqlDbType.NChar, 5, CustomerID);  myParm.SourceVersion DataRowVersion.Original;  myParm custDA.UpdateCommand.Parameters.Add(oldCompanyName, SqlDbType.NVarChar, 30, CompanyName);  myParm.SourceVersion DataRowVersion.Original;  // Add the RowUpdated event handler.  custDA.RowUpdated new SqlRowUpdatedEventHandler(OnRowUpdated);  DataSet custDS new DataSet();  custDA.Fill(custDS, Customers);  // Modify the DataSet contents.  custDA.Update(custDS, Customers);  foreach (DataRow myRow in custDS.Tables[Customers].Rows)  {     if (myRow.HasErrors)       Console.WriteLine(myRow[0] n myRow.RowError);  } protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args) {  if (args.RecordsAffected 0)  {     args.Row.RowError Optimistic Concurrency Violation Encountered;     args.Status UpdateStatus.SkipCurrentRow;  } }         III协作设计             在你写期间你应当锁定DataSet。         IV仅当需要的时候才使用COM对象访问ADO             ADO.NET设计为大量应用程序最好的解决方案。然而一些应用程序需要只有ADO对象才能提供的功能比如ADOMD。这种情况下可以使用COM对象访问ADO注意的是使用COM对象访问ADO数据会影响应用程序的执行效率。所以在设计应用程序时首先应该考虑在使用COM对象访问ADO数据之前看看ADO.NET是否就满足你的设计要求。     VADO.NET和ADO的比较         IADO.NET在ADO设计模型的基础上演变和发展而来它并不取代COM程序员的ADO更多地它是为.NET程序员访问相关数据源、XML和应用程序数据设计。ADO.NET支持多样化的发展要求包括创建数据库客户端和供应用程序、工具、语言、WEB浏览器等使用的中间层业务对象。ADO.NET与ADO有许多相似的地方。         IIADO为COM程序员提供了高效的、强大的与数据库打交道的各种接口。ADO能得到广泛的运用是因为它支持任何的自动化控制语言比如VC、VB和脚本语言等的调用。ADO基础上升级而来的ADO.NET提供更好的交互平台和可升级的数据访问。在ADO.NET中创建一个新的数据访问API集能提供较之于ADO接口几个优越的地方如下所述             ①改进了与XML的结合             随着XML在应用程序中扮演着越来越重要的角色与XML结合的ADO.NET就应运而生。为了持续和装载数据以及数据的XML格式ADO.NET依赖XML在多层之间或客户机之间远程传递数据。ADO.NET中使用的特殊XML表述形式提供在任何网络中十分便利地传输数据的方法包括数据安全边界。同时ADO.NET使用XML工具执行确认、分级查询和数据和数据之间的转换。             ②综合.NET框架             ADO结构如Recordset并不使用常见的设计结构相反它模拟成一种数据导向。举例ADO中的用来导航和得到数据的游标它的功能性就与其它的比如数组和集合数据结构不同。然而在ADO.NET中因为存储的数据能通过公共的.NET框架结构暴露包括数组和集合所以你可以使用一些公共的方法与你的相关数据打交道。             ③改良对离散业务模型的支持             ADO使用Recordset提供有限的对离散访问的支持。ADO.NET介绍一个新的对象DataSet它作为相关数据的一个公共的、存储的表现形式在任何时候都被设计为离散的它与外部数据并不保持持久的连接它是包装、存储、交换、延续和装载数据的好方法。也就是说任何对数据的操作都是在本地进行而不直接与真实的数据库打交道。             ④数据访问行为的控制是清楚的             ADO中包括在应用程序中并不总是要求和指定的隐含行为会限制应用程序的性能。而在ADO.NET中提供良好的定义和预先的行为、执行和语义要素组件使得你可以在一个高优化的方式下定位到一个普通的情节上。             ⑤改善设计阶段的支持             ADO源自执行阶段隐含的数据信息而这种信息是基于花费昂贵代价才获得的元数据。在ADO.NET中的元数据只是在设计阶段起一个杠杆作用从而提供执行阶段更好的性能和更好的稳定性。         IIIADO设计             为了更好地理解ADO.NET模型和设计思想回顾一下ADO的概念是有用的。ADO使用一个单一的对象Recordset与所有数据类型打交道。Recordset被用来处理从数据库返回的只进流数据、翻卷服务器上数据或者翻卷一批存储结果集。数据上的改变会立即运用到数据库上或运用到使用乐观查询和更新操作的一批数据上。当你创建一个Recordset时你就明确了你所作的任务Recordset结果行为的改变主要取决于你要求的Recordset参数。因为ADO使用一个单一的能在很多场合使用的Recordset对象这使得你的应用程序中的对象模型很简单。然而也很难写一个公用的、可预言的和最优化的代码那是因为行为、执行和一个单一对象描述的语义要得到改变很大程度上取决于对象是如何创建和对象访问的是什么数据。         IVADO.NET设计             ADO.NET是考虑到开发者在访问和使用数据时共同面对的任务和问题而设计。宁可使用一个单一对象执行大量任务还不如如ADO.NET中指定每个对象的功能性因素去完成对应的每个任务。ADO中的Recordset功能性被分解成ADO.NET中以下的几个清楚对象DataReader提供快速的、只进的和只读的访问去查询结果DataSet存储数据DataAdapter在DataSet和数据源之间架起一道桥梁ExecuteNonQuery不返回行ExecuteScalar返回一个单一值而不是一个行集。下面是一些详细说明             ①只进、只读数据流             应用程序特别是中间层应用程序经常要程序化地处理一系列结果要求在他们读的时候没有用户交互和没有更新或回滚结果。在ADO中执行这类数据时使用Recordset的只进游标和只读锁。在ADO.NET中DataReader优化了这种数据的执行性能它通过提供一个非缓冲、只进和只读的数据流从数据库得到数据。             ②返回单一值             在ADO中要得到一个单一值你需要通过创建一个Recordset—〉读取结果—〉得到单一值—〉关闭Recordset这样一个过程。在ADO.NET中你就可以使用Command对象的ExecuteScalar方法不需要额外的操作来获得单一值。             ③离散数据访问             ADO使用客户端游标定位离散数据的访问而在ADO.NET中DataSet可以很清楚地实现离散数据的访问。DataSet能从一个多样的不同的数据源提供一个公有的、完全离散的数据表现形式是因为DataSet是完全独立于数据源的。它不管你数据是从数据库来的还是从XML文件来的抑或是从应用程序中得到的。一个简单的DataSet可以装载从多个不同数据库或非数据库源的数据。然后使用DataRelation在多个表之间建立一个连接尽管Recordset的MsDataShape提供者可以实现分级结构查询但是DataSet提供更高的稳定性处理离散数据。同时DataSet提供以XML文件格式在远程客户端和服务器之间传输数据。             ④从数据库得到数据和更新数据             ADO.NET提供更好的执行阶段性能和可见性。举例当使用ADO的Recordset对象进行批更新时你必须为每个需要改变结果的行使用UPDATE、INSERT或DELETE声明。ADO产生这些声明在执行阶段是需要付出昂贵代价的获得元数据的。而在ADO.NET中指定UPDATE、INSERT或DELETE命令就如同自定义业务逻辑比如一个存储过程一样你可以使用DataAdapter实现这一切。DataAdapter在DataSet和数据源之间架起一道桥梁。让你在执行阶段就不是如ADO的Recordset一样需要在数据源中收集元数据信息。从而改善应用程序的执行性能。         V数据类型             在ADO中所有的结果返回一个Variant数据类型在ADO.NET中你可以得到列本身的数据类型。数据类型可以在System.Data.SqlTypes名称空间定义。     W有关ADO和ADO.NET的详细介绍请参考微软上的资料ADO.NET for the ADO Programmer     总结     通过本文希望与大家共同交流和学习有不当之处请大家指正谢谢 转载于:https://www.cnblogs.com/feima-lxl/archive/2008/07/12/1241225.html
http://www.zqtcl.cn/news/963272/

相关文章:

  • 刘涛做代言的那个网站设计与制作
  • 专业网站建站星辰wordpress主题
  • 淄博个人网站建设天津网站制作机玩法部
  • 帮人做图挣外快的网站seo优化教学视频
  • 做房产中介需要有内部网站吗烟台开发区网站建设
  • 网站资质优化网站备案密码使用
  • 廊坊营销网站团队网站推广报告
  • 商品网站模板多语言企业网站模板
  • 佛山网页制作设计东莞seo推广机构帖子
  • 公司网站开发费用如何入账网站开发与设计实训总结两千字
  • 生物网站模板在线crm厂商
  • 在线制作动画网站ps切图做网站
  • 西安企业网站建设公司虚拟主机可以做视频网站嘛
  • 做淘客网站用什么程序今天杭州新闻最新消息
  • 东莞专业建网站网站制作方案相信乐云seo
  • 网站分页符素材怎么解决
  • 行远金华网站建设公司合肥公司做网站
  • 餐厅类网站模板中国电建市政建设集团有限公司网站
  • 格力网站建设首页六盘水遵义网站建设怎么做
  • 建设工程企业资质工作网站创建网站怎么赚钱的
  • 三水网站建设流感吃什么药最好
  • 洛阳市住房和城乡建设局网站怎么查询企业注册信息
  • 商业摄影网站源码wordpress文章作者
  • 昆明企业网站模板建站漳浦建设局网站更新
  • 企业网站建设策划书微信开发者工具是干嘛的
  • 泵 品牌网站建设WordPress头像不能本地化
  • vue快速建站网站开发法律
  • 家居行业网站开发百度竞价推广账户
  • 粉色大气妇科医院网站源码百度网址大全网址
  • wordpress 留言墙插件优化网站搭建