• 数据库ADONET使用DataAdapter对象


     

    DataAdapter

    如果想将查询结果存储在DataSetDataTable对象中,比较简单的是使用DataAdapter对象。

    1          DataAdapter对象

    DataAdapter类是ADO.NET对象模型中联机和脱机这两部分的桥梁。

    l         DataAdapter能将数据从数据库取出,再放到DataSet中;

    l         DataAdapter还可以提取DataSet中存储在缓存中的更新数据,并提交给数据库

    1.1         DataAdapter特性

    DataAdapter对象,感觉上,好像与ADOCommand对象、RDOrdoQuery对象、DAOQueryDef对象相似;但是它们的差异明显。

    1.1.1            DataAdapter的设计目的是处理脱机数据

    DataAdapter是专门为处理脱机数据而设计的。

    最好的例子是Fill方法,调用Fill方法可以不需要DataAdapter拥有与数据库间的活动连接:若在当前未开放的连接上调用FillDataAdapter会开发连接、查询数据库,然后填充结果到DataSet,最后关闭连接。

    1.1.2            DataAdapterDataSet间没有直接连接

    DataAdapter对象的Fill方法中传递DataSet对象作为参数,可以填充DataSet中的DataTable

    l         代码:

    OleDbDataAdapter.Fill(DataSet)

    调用Fill完成后,两个对象之间就没有连接了。(DataSet不会保存任何内在的或外在的对DataAdapter的引用;DataAdapter也不会保留对DataSet的引用);DataSet不包含任何表明数据来源的信息(例如:连接字符串、表格名、列名称)。

    因此,可以将DataSet对象从中间层服务器传递到客户端应用程序,不必担心泄露关于数据库位置与结构的信息。

    1.1.3            DataAdapter中能包含回递给数据库的更新逻辑(存储在DataSet中)

    DataAdapter也可以向数据库回递待定的更改。(这是与过去的数据访问模型的主要区别)

    使用DataAdapterUpdate方法提交更改。调用时需要DataSet对象作为参数。(DataSet能够缓存更改)

    注意:实际的更新逻辑包含在DataAdapter对象中。

    1.1.4            控制DataAdapter的更新逻辑

    DataAdapter中,可以自定义insertupdatedelete查询,或使用存储过程提交更新。

    DataAdapter拥有四项属性包含了Command对象,通过它们就可以分别指定自己的操作查询或存储过程;同样也可以分别指定能将数据在DataSet和存储过程之间来回移动的参数。

    1.2         DataAdapter剖析(研究它的结构以及运作方式)

    DataAdapter的设计目的在于帮助你将查询结果存储在DataSet对象和DataTable对象之中。

    Command对象允许通过DataReader对象浏览查询结果。

    DataAdapter对象由一系列Command对象组成,还包括一组用于确定DataAdapterDataSet通信关系的映射属性。

    1.2.1            子命令

    使用DataAdapter将查询结果存储在DataSet中时,DataAdapter会使用一个Command对象来与数据库通讯;DataAdapter对象内在的使用了DataReader来取得结果数据,然后将信息复制到DataSet的新行去。(用循环逐行)

    DataAdapter对象取数据的Command对象在其SelectCommand属性中。

    插入数据的Command在其InsertCommand属性;删除数据的Command在其DeleteCommand属性;更新数据的Command在其UpdateCommand属性。

    1.2.2            TableMapping集合

    默认时,DataAdapter假设DataReader中的列与DataSet中的列是相匹配的。

    如果,你希望DataSet的架构与数据库中的架构不同(一种可能是想给DataSet中的特定列使用不同的名称):传统作法是,在查询中给列指定别名;现在,你可以使用TableMappings集合机制。

    DataAdapter对象的TableMappings集合允许创建一个数据库和DataSet之间的映射层。

    TableMappings属性返回一个DataTableMappingsCollection对象。

    DataTableMappingsCollection对象含有一组DataTableMapping对象,其中每个对象都允许你在数据库中的某一个表(或视图、存储过程)与DataSet相应表之间创建映射。

    DataTableMapping对象含有一个ColumnMappings属性,它返回一个DataColumnMappingCollection对象。

    DataColumnMappingCollection对象是由一组DataColumnMapping对象组成的集合,每一个DataColumnMapping都能将数据库一列映射为DataSet一列。

     

    l         代码演示(填充TableMappings集合)

    Dim da As OleDbAdapter

    初始化Adapter

    Dim tblMap as DataTableMapping

    Dim colMap as DataColumnMapping

    将表名对应

    tblMap=da.TableMappings.Add(“Table”,”Employee”)

    将列名对应

    colMap=tblMap.ColumnMappings.Add(“EmpID”,”EmployeeID”)

    colMap=tblMap.ColumnMappings.Add(“LName”,”LastName”)

    colMap=tblMap.ColumnMappings.Add(“FName”,”FirstName”)

    2          创建和使用DataAdapter对象

    2.1         创建DataAdapter

    注意:创建DataAdapter对象时,一般都希望SelectCommand属性是可用的Command对象。

    l         代码

    Dim strConn as String=”…”

    Dim cn as new OleDbConnection(strConn)

    Dim ssql as string=”select CustomerID,CompanyName from Customers”

    Dim cmd as new OleDbCommand(ssql,cn)

    Dim da as new OleDbAdapter()

    da.SelectCommand=cmd

    2.2         DataAdapter的构造函数

    DataAdapter4个构造函数(3个是带参数的):

    l              Public Sub New(ByVal selectCommand As OleDbCommand)

    使用一个存在的Command作为SelectCommand使用

    l              Public Sub New(ByVal selectCommandText As String, ByVal selectConnection As OleDbConnection)

    使用一个存在的Connection连接对象,并根据传入的查询SQL潜在的构造SelectCommand对象

    l              Public Sub New(ByVal selectCommandText As String, ByVal selectConnectionString As String)

    此构造函数,潜在的为新DataAdapter构造一个Connection对象,并潜在的构造SelectCommand对象。

    2.3         从查询中取得结果

    2.3.1            使用Fill方法

    调用Fill会:

    1.        执行存储在SelectCommand属性中的查询

    2.        将查询结果存储在DataSet中,如果未指定,则数据放在新创建的默认的DataTable对象(名Tabe

    n         代码:

    Dim strConn,strSql as String

    strConn=”…”

    strSql=”Select CustomerID,CompanyName,ContactName,Phone from Customers”

    Dim da as New OleDbDataAdapter(strSql,strConn)

    Dim ds As new DataSet()

    da.Fill(ds)

    2.3.2            使用Fill方法创建DataTable对象和DataColumn对象

    Fill方法会在DataSet对象中创建新的DataTable(如果没有指定DataTable名的话默认为‘Table’)此DataTable的列结构与查询结果相同。

    TableMappings集合中添加新TableMapping项目可以修改查询结果,改变其映射关系。

    n         代码

    Dim da as new OleDbDataAdapter(strSql,strConn)

    Da.TableMappings.Add(“Table”,”Customers”) ‘此处将查询结果映射到名叫CustomersDataTable

    Dim ds as new DataSet()

    da.Fill(ds)

    2.3.3            使用重载的Fill方法

    Fill的不同重载版本可以拥有更多的控制权。

    2.3.3.1      指定DataTable

    有两个Fill重载版本可以指定DataTable(这使你更灵活的控制DataTable

    2.3.3.1.1          填充时指定表名称

    DataAdapter.Fill(DataSet,”MyTableName”)

    2.3.3.1.2          填充时指派DataTable对象(而非DataSet

    DataAdapter.Fill(DataTable)

    2.3.3.2      根据DataAdapter对象的Fill方法分页

    Fill的一个重载版本可以获取查询结果的一部分(实现一部分分页的效果)

    DataAdapter.Fill(DataSet,intStartRec,intRecCount,”Table Name”)

    但是,你要牢记一点,即使你指定返回的是一部分结果,Fill方法还是将所以查询结果都返回,只不过将不需要的删去了。

    所以,Fill方法简化查询分页的效率很一般。

    2.3.3.3      DataAdapter对象将一个Recordset的内容填充到DataSet对象

    OLEDB.NET数据提供者的两个Fill重载版本,可以将数据从ADO Recordset复制到ADO.NETDataSet

    2.3.3.3.1          OleDbAdapter.Fill(DataSet,AdoRecordset,”Table Name”)

    2.3.3.3.2          OleDbAdapter.Fill(DataTable,AdoRecordset)

    2.3.4            开放和关闭连接

    n         DataAdapter对象和Command对象处理Connection对象的方法存在差异。

    Command对象需要一个开放的Connection对象,否则Command会有异常。

    DataAdapter对象没有这个限制。

    调用DataAdapter.Fill方法(SelectCommandConnection是关闭状态),DataAdapter会先开放连接,然后提交查询、取结果,最后关闭连接。

    有时候,连续的使用DataAdapterFill方法,会使Connection对象连续的开放和关闭。怎么办?你可以给多个DataAdapter对象指定同一个Connection对象,并且在使用Fill方法之前,就用Connection.Open方法打开连接。

    2.3.5            多次调用Fill方法

    想一想:如何刷新DataSet中的数据,以便使用户能看到即时的更改。

    最简单的办法就是清空DataSet或者DataTable,然后再次调用DataAdapterFill填充。

    假使没有清空就连续调用(两次)Fill方法,那么你会在DataSetDataTable中看到多个(两个)客户记录

    对代码段来说,DataAdapter不能知道哪些客户是重复的。

    通常,数据库的表中会定义一个主键。这样,能防止用户创建重复的行。

    DataTable对象也有一个PrimaryKey属性。如果DataAdapter所填充的DataTable有一个主键,那么DataAdapter就会利用该主键来确定哪些行是重复的。(因此,在第一次填充后定义了DataTable的主键,那么第二次的填充DataAdapter会定位重复的行,删去旧值。)

    下面假设第一次填充时,有一个客户记录被添加到DataTable中,之后,该客户记录被从数据库中删除了;此时如果进行第二次填充,客户记录会更新吗?不会,DataAdpater在查询结果中找不到该客户的信息,而且也不会将它从DataTable中删除。

    想一想:怎么刷新全部数据?要先清空DataSetDataTable,然后再次调用DataAdapter.Fill方法。(这样能确保没有重复行,同时确保数据库中没有的行不添加进DataSet

    2.4         将查询结果映射到DataSet

    使用DataAdapter对象的TableMappings集合

    2.4.1            DataAdapter对象的TableMappings集合

    TableMappings集合用来控制DataAdapterDataSet映射到数据库的方式

    填充时,将TableMappings保留为空,调用Fill,然后将DataSet作为参数传递,且不指定表名称,DataAdapter会假定你要处理的是(名为Table)的DataTable

    TableMappings属性返回一个类型为DataTableMappingCollection的对象。该对象内含多个DataTableMapping对象。可以如下添加:

    DataAdapter.TableMappings.Add(“Table”,”Employees”) 告知DataAdapter与名为EmployeesDataTable通讯

    创建表映射之后,下一步可以创建列映射。例如:

    Dim da as OleDbDataAdapter

    Dim tblMap as DataTableMapping

    Dim colMap as DataColumnMapping

    tblMap=da.TableMappings.Add(“Table”,”Employees”)

    colMap=tblMap.ColumnMappings.Add(“EmpID”,”EmployeeID”)

    colMap=tblMap.ColumnMappings.Add(“Lname”,”LastName”)

    colMap=tblMap.ColumnMappings.Add(“Fname”,”FirstName”)

    2.4.2            MissingMappingAction属性

    绝大多数情况下,开发人员在DataSet中都会使用与数据库中表相同的列名称。

    DataAdapter检查查询结果时,若发现某一列在其映射集合中不存在,它会检查MissingMappingAction属性以确定如何处理这些列。

    MissingMappingAction属性接受System.Data名称空间中MissingMappingAction枚举类型的值。

    默认值为Passthrough,表示DataAdapter将缺失的列映射为DataSet中同名的列;

    Ignore,表示忽略缺失的列;

    Error,表示若有缺失列时,会产生异常。

    2.5         处理批查询

    MS-Sql Server允许执行批查询。

    Select CustomerID,CompanyName,ContactName,Phone from Customers where CustomerID=”ALFKI”

    Select OrderID,CustomerID,EmployeeID,OrderDate from Orders where Customer=”ALFKI”

    如果使用DataAdapter.Fill(DataSet)的方式取得DataSet,将会在DataSet中产生两个DataTable对象。每个DataTable保存一个查询的结果。一个名叫“Table”,一个名叫“Table1

    2.6         从存储过程中获取行

    假设是Sql Server的存储过程(它能返回结果集)如下:

    Create procedure GetAllCustomers as

           Select CustomerID,CompanyName,ContactName,Phone from Customers

    Return

    使用DataAdapter允许它并取得结果集放入DataSetDataTable中。你可以使用下面的查询语句(两个)之一:

    {CALL GetAllCustomers}EXEC GetAllCustomers

    另外,如果需要使用Command对象的CommandType属性作为DataAdapterSelectCommand的话,还可以有更多的控制功能。

    对于Oracle的存储过程,它不能从查询中返回行,仅能通过输出参数返回数据。

    OracleOLEDB提供者和OracleODBC驱动程序允许开发者调用Oracle的存储过程,并通过输出参数取得查询结果。)

    因此,Oracle的查询语法如下:

    {CALL PackageName.ProcName (?, {resultset 20, OutParam1, OutParam2, …})}

    2.7         获取架构信息

    设计DataTable的目的在于加强数据上的约束,比如主键、字符串字段最大长度以及可空性限制等。

    多数情况下,开发者不需要这些信息,DataAdapter能通过一些关键属性取得架构信息­——比如MissingSchemaAction属性和FillSchema方法

    2.7.1            MissingSchemaAction属性

    Fill方法使用的是不包含架构信息的DataSet对象和DataTable对象。

    默认情况下,DataSetDataTable没有那些列,DataAdapter会添加列信息来存储查询结果,这个操作就是有MissingSchemaAction来管理的。

    MissingSchemaAction属性接受System.Data.MissingSchemaAction枚举类型的值。

    默认值Add

    可能值Ignore,表示忽略缺失列

    可能值Error,表示有缺失列就产生异常。

    可能值AddWithKey,表示有缺失列时,会在DataSet中添加缺失列,并且,设置MissingSchemaAction属性的两个附加属性:MaxLengthAllowDBNull。如果DataTable不存在或者DataTable不包含任何列,还会导致DataAdapter向数据库查找有关的主键信息。

    2.7.2            FillSchema方法

    此方法将架构信息存入DataSetDataTable.

    此方法可以使用的参数:DataSetDataTableDataSet,表名称。

    另外一个需要的参数是:SchemaType类型的值,取值MappedSource。(其中Mapped值将使DataAdapter使用TableMappings表映射的设置来应用返回列;而Source值则让DataAdapter使用查询结果来应用返回列)

    另外,FillSchema方法会给返回列设置自增量(AutoIncrement)、允许空(AllowDBNull)、最大长度(MaxLength)等属性。

    如果数据库中某列或某组列表示主键(或唯一键),FillSchema方法还要在结果DataTable上创建主键。

  • 相关阅读:
    gatsby head of headless CMS
    nginx load balance
    dataset databases for lazy people
    The TwelveFactor App
    D Div Game ATCODER
    FASTAPI OAuth2 Scopes
    Machine learning model serving in Python using FastAPI and streamlit
    only using python to make web app
    DI(Dependency Injection) of FASTAPI
    D Takahashi's Solitaire ATCODER
  • 原文地址:https://www.cnblogs.com/lizunicon/p/1299928.html
Copyright © 2020-2023  润新知