首页 > 编程 > .NET > 正文

ADO.NET最佳实践(上)

2024-07-21 02:08:40
字体:
来源:转载
供稿:网友

    概述:

    本文在微软站点资源的基础上加工整理而成,意在介绍在你的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 provider,ole 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 source=localhost;integrated security=sspi;" & _                                                   "initial catalog=northwind")

nwindconn.open()

‘c#

sqlconnection nwindconn = new sqlconnection("data source=localhost; integrated security=sspi;" +

"initial catalog=northwind");

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};server=localhost;" & _                                                     "trusted_connection=yes;database=northwind")

nwindconn.open()

‘c#

odbcconnection nwindconn = new odbcconnection("driver={sql server};server=localhost;" +

"trusted_connection=yes;database=northwind");

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最优化对数据的访问。

    f.dataset和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 source=localhost;integrated security=sspi;" & _

"initial catalog=northwind;")

dim custda as sqldataadapter = new sqldataadapter("select * from customers", custconn)

dim orderconn as oledbconnection = new oledbconnection("provider=microsoft.jet.oledb.4.0;" & _                                                       "data source=c:/program files/microsoft office/" & _                                                       "office amples/northwind.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 source=localhost;integrated security=sspi;initial catalog=northwind;");

sqldataadapter custda = new sqldataadapter("select * from customers", custconn);

oledbconnection orderconn = new oledbconnection("provider=microsoft.jet.oledb.4.0;" +                                                "data source=c://program files//microsoft office//office/ amples//northwind.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 source=localhost;integrated security=sspi;initial catalog=northwind")

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(namespace="http://microsoft.com/webservices/")]

45.  public class sample

46.  {

47.    public sqlconnection nwindconn = new sqlconnection("data source=localhost;integrated security=sspi;initial catalog=northwind");

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:xsl="http://www.w3.org/1999/xsl/transform" version="1.0">

<xsl:template match="customerorders">

  <html>

  <style>

  body {font-family:verdana;font-size:9pt}

  td   {font-size:8pt}

  </style>

    <body>

    <table border="1">

      <xsl:apply-templates select="customers"/>

    </table>

    </body>

  </html>

</xsl:template>

<xsl:template match="customers">

    <tr><td>

      <xsl:value-of select="contactname"/>, <xsl:value-of select="phone"/><br/>

    </td></tr>

      <xsl:apply-templates select="orders"/>

</xsl:template>

<xsl:template match="orders">

  <table border="1">

    <tr><td valign="top"><b>order:</b></td><td valign="top"><xsl:value-of select="orderid"/></td></tr>

    <tr><td valign="top"><b>date:</b></td><td valign="top"><xsl:value-of select="orderdate"/></td></tr>

    <tr><td valign="top"><b>ship to:</b></td>

        <td valign="top"><xsl:value-of select="shipname"/><br/>

        <xsl:value-of select="shipaddress"/><br/>

        <xsl:value-of select="shipcity"/>, <xsl:value-of select="shipregion"/>  <xsl:value-of select="shippostalcode"/><br/>

        <xsl:value-of select="shipcountry"/></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 source=localhost;initial catalog=northwind;integrated security=sspi")

    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 source=localhost;initial catalog=northwind;integrated security=sspi;");

    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();

  }

}

ado.net最佳实践(中)

http://www.csdn.net/develop/read_article.asp?id=22663
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表