国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

ADO.NET中的多數據表操作淺析—讀取

2024-07-10 13:03:12
字體:
來源:轉載
供稿:網友
ado.net中的多數據表操作淺析—讀取

作者:鄭佐??????? 2004-8-5

???????? 在開發基于.net平臺的數據庫應用程序時,我們一般都會用到dataset,作為ado.net的核心類它為我們提供了強大的功能,而整個看上去就像是放在內存內的一個小型數據庫,內部包括了datatable、dataview、datarow、datacolumn、constraint以及datarelation。當初看到它時真的是有點興奮。

???????? 下面根據我的一些經驗來舉例說明在ado.net中的多表填充、關聯表更新以及多個command對象執行過程中啟用事務的操作。歡迎大家交流,或在blog上留言。

????????

一、準備工作

???????? 對于northwind數據庫大家都比較熟悉,所以這里拿它為例,我把customers(客戶表)、orders(訂單表)、order details(訂單詳細表)合起來建立了一個類型化的數據集,類型名稱為datasetorders,每個表只包括一些字段,下面是在visual studio .net中建立的一個截圖:

?

圖1-1

上面建立了兩個關系表示為customers —> orders —>order details。因為orders表的orderid字段為自動增長列,這里把就把它的autoincrementseed和autoincrementstep值設置成了-1,這在實際添加訂單的過程中可能會比較明顯,不過不設也沒問題。

????????

二.填充數據集

建立一個窗體程序來演示實際的操作,界面如下:



圖2-1

整個應用程序就是一個form,上面的三個datagrid分別用來顯示相關表的數據,不過他們是互動的。另外的兩個單選框用來決定更新數據的方式,兩個按鈕正如他們的名稱來完成相應的功能。

這里我們用一個dataadapter來完成數據集的填充,執行的存儲過程如下:

create procedure getcustomerordersinfo

as

select customerid,companyname,contactname from customers where customerid like 'a%'

?

select orderid,orderdate,customerid from orders? where customerid in

(select customerid from customers where customerid like 'a%')

?

select orderid,productid,unitprice,quantity,discount from [order details] where orderid in

(select orderid from orders? where customerid in

(select customerid from customers where customerid like 'a%'))

?

go

?

為了減少數據量,這里只取了customerid以’a’開頭的數據。

建立dataaccess類來管理窗體同數據層的交互:

using system;

using system.data;

using system.data.sqlclient;

using microsoft.applicationblocks.data;

?

namespace winformtest

{

???? public class dataaccess

???? {

???????? private string _connstring = "data source=(local);initial catalog=northwind;uid=csharp;pwd=c#.net2004;";

???????? private sqlconnection _conn;

???????? ///構造函數

public dataaccess()

???????? {

????????????? _conn = new sqlconnection(_connstring);

}

下面的函數完成單個數據適配器來完成數據集的填充,

public void fillcustomerordersinfo(datasetorders ds)

???? ???? {

????????????? sqlcommand comm = new sqlcommand("getcustomerordersinfo",_conn);

????????????? comm.commandtype = commandtype.storedprocedure;

????????????? sqldataadapter dataadapter = new sqldataadapter(comm);

????????????? dataadapter.tablemappings.add("table","customers");

????????????? dataadapter.tablemappings.add("table1","orders");

????????????? dataadapter.tablemappings.add("table2","order details");

????????????? dataadapter.fill(ds);

???????? }

如果使用sqlhelper來填充那就更簡單了,

???????? public void fillcustomerordersinfowithsqlhelper(datasetorders ds)

???????? {???????????? sqlhelper.filldataset(_connstring,commandtype.storedprocedure,"getcustomerordersinfo",ds,new string[]{"customers","orders","order details"});

???????? }

叉開話題提一下,data access application block 2.0中的sqlhelper.filldataset這個方法超過兩個表的填充時會出現錯誤,其實里面的邏輯是錯的,只不過兩個表的時候剛好湊巧,下面是從里面截的代碼:

private static void filldataset(sqlconnection connection, sqltransaction transaction, commandtype commandtype,

????????????? string commandtext, dataset dataset, string[] tablenames,

????????????? params sqlparameter[] commandparameters)

???????? {

????????????? if( connection == null ) throw new argumentnullexception( "connection" );

????????????? if( dataset == null ) throw new argumentnullexception( "dataset" );

????????????? sqlcommand command = new sqlcommand();

????????????? bool mustcloseconnection = false;

????????????? preparecommand(command, connection, transaction, commandtype, commandtext, commandparameters, out mustcloseconnection );

??? ????????? using( sqldataadapter dataadapter = new sqldataadapter(command) )

????????????? {

???????? ????????? if (tablenames != null && tablenames.length > 0)

?????????????????? {

?????????????????????? string tablename = "table";

?????????????????????? for (int index=0; index < tablenames.length; index++)

?????????????????????? {

??????????????????????????? if( tablenames[index] == null || tablenames[index].length == 0 )

???????????????????????????????? throw new argumentexception( "the tablenames parameter must contain a list of tables, a value was provided as null or empty string.", "tablenames" );

??????????????????????????? tablename += (index + 1).tostring();//這里出現錯誤

?????????????????????? }

?????????????????? }

?????????????????? dataadapter.fill(dataset);

?????????????????? command.parameters.clear();

????????????? }

????????????? if( mustcloseconnection )

?????????????????? connection.close();

???????? }

?

這里把tablename += (index + 1).tostring();修改成

dataadapter.tablemappings.add((index>0)?(tablename+index.tostring()):tablename, tablenames[index]);就能解決問題。

?

接下來看看窗體程序的代碼:

public class form1 : system.windows.forms.form

???? {

???????? private dataaccess _dataaccess;

???????? private datasetorders _ds;

???????? //……

???????? //構造函數

???????? public form1()

???????? {

????????????? initializecomponent();

????????????? _dataaccess = new dataaccess();

????????????? _ds = new datasetorders();

????????????? _ds.enforceconstraints = false; //關閉約束檢查,提高數據填充效率

????????????? this.datagridcustomers.datasource = _ds;

????????????? this.datagridcustomers.datamember = _ds.customers.tablename;

????????????? this.datagridorders.datasource = _ds;

????????????? this.datagridorders.datamember = _ds.customers.tablename+"."+_ds.customers.childrelations[0].relationname;

????????????? this.datagridorderdetails.datasource = _ds;

????????????? this.datagridorderdetails.datamember = _ds.customers.tablename+"."+_ds.customers.childrelations[0].relationname+"."+_ds.orders.childrelations[0].relationname;

???????? }

對于上面的三個表的動態關聯,你也可以使用setdatabinding方法來完成數據的動態綁定,而不是分別指定datagride的datasource和datamemger屬性。

this.datagridcustomers.setdatabinding(_ds,_ds.customers.tablename);

this.datagridorders.setdatabinding(_ds,_ds.customers.tablename+"."+_ds.customers.childrelations[0].relationname);

this.datagridorderdetails.setdatabinding(_ds,_ds.customers.tablename+"."+_ds.customers.childrelations[0].relationname+"."+_ds.orders.childrelations[0].relationname);

}

數據填充事件處理如下:????????????????????????

private void buttonfilldata_click(object sender, system.eventargs e)

???????? {

????????????? _ds.clear();//重新填充數據集

????????????? _dataaccess.fillcustomerordersinfo(_ds);

????????????? //_dataaccess.fillcustomerordersinfowithsqlhelper(_ds);

???????? }

執行上面的事件處理函數我們會看到數據顯示到對應的datagrid上,如(圖2-1)所示。

如果使用數據讀取器獲取多表紀錄下面是實現的一種方式(參考):

sqlcommand comm = new sqlcommand("getcustomerordersinfo",_conn);

comm.commandtype = commandtype.storedprocedure;

_conn.open();

sqldatareader reader = comm.executereader();

do

{

???? while(reader.read())

???? {

???????? console.writeline(reader[0].tostring());//獲取數據代碼

???? }

}while(reader.nextresult());

console.readline();

_conn.close();

?

?




收集最實用的網頁特效代碼!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 申扎县| 台南县| 保德县| 八宿县| 崇礼县| 临猗县| 德令哈市| 合作市| 嘉鱼县| 菏泽市| 黄梅县| 安塞县| 策勒县| 本溪市| 加查县| 东至县| 漯河市| 荆门市| 思南县| 龙门县| 康马县| 天祝| 石楼县| 额尔古纳市| 枣阳市| 九寨沟县| 佛坪县| 正安县| 盐池县| 通渭县| 哈密市| 长沙市| 嘉兴市| 名山县| 揭阳市| 沛县| 潮安县| 玉山县| 高清| 沂南县| 双辽市|