免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
DataBase和DataSet同步數(shù)據(jù)

DataBase和DataSet同步數(shù)據(jù)
數(shù)據(jù)適配器概述
l         DataAdapter 連接到數(shù)據(jù)庫(kù)以填充DataSet 的對(duì)象。然后,它又連接回?cái)?shù)據(jù)庫(kù),根據(jù)DataSet 保留數(shù)據(jù)時(shí)所執(zhí)行的操作來(lái)更新數(shù)據(jù)庫(kù)中的該數(shù)據(jù)。

l         DataAdapter:它起著橋梁的作用,在DataSet 和其源數(shù)據(jù)存儲(chǔ)區(qū)之間進(jìn)行數(shù)據(jù)檢索和保存.

l         DataAdapter對(duì)象可以隱藏和Connection、Command對(duì)象溝通的細(xì)節(jié),通過(guò)DataAdapter對(duì)象建立、初始化DataTable,從而和DataSet對(duì)象結(jié)合起來(lái)在內(nèi)存存放數(shù)據(jù)表副本,實(shí)現(xiàn)離線式數(shù)據(jù)庫(kù)操作.

數(shù)據(jù)適配器的屬性
l         數(shù)據(jù)源更新

– InsertCommand

– SelectCommand

– DeleteCommand

– UpdateCommand

l         TableMappings:用于維持?jǐn)?shù)據(jù)集中的列和數(shù)據(jù)源中列的關(guān)系

l         AcceptChangesDuringFill:決定AccepChnages方法是否被添加到數(shù)據(jù)集中的每一行所調(diào)用,默認(rèn)為true

TableMappings集合
l         數(shù)據(jù)集和數(shù)據(jù)源的橋梁:

– 數(shù)據(jù)集并不清除它所包含的數(shù)據(jù)從哪里來(lái),而Connection也不知道它所檢索的數(shù)據(jù)都發(fā)生了什么改變。

– 數(shù)據(jù)適配器用于維持這兩者之間的聯(lián)系,它通過(guò)TableMappings集合來(lái)實(shí)現(xiàn)這一目標(biāo)。

l         包括

– DataTableMappings

– DataColumnMappings

1.         SourceColumn

2.         DataSetColumn

 

 

 

[參考代碼]

protected  System.Web.UI.WebControls.DropDownList  ddlClassCode;

//省略

SqlDataAdapter da = new SqlDataAdapter("select Distinct classCode from tbClassInfo",con);

DataSet ds = new DataSet("myDs");

da.Fill(ds,"Class");

ddlClassCode.DataTextField = "ClassCode";

ddlClassCode.DataSource = ds.Tables["Class"].DefaultView;

ddlClassCode.DataBind();

 

ddlClassCode.SelectedIndex = nIndex;

string strSelectedClass = ddlClassCode.SelectedItem.Text;

string strSql = "select * from tbStudentInfo where StudentID in (select studentid from tbClassInfo where classcode='"+strSelectedClass+"')";

da.SelectCommand.CommandText =strSql;

//映射

da.TableMappings.Add("tbStudentInfo","Student");

da.TableMappings[0].ColumnMappings.Add("StudentID","學(xué)生ID");

da.TableMappings[0].ColumnMappings.Add("StudentName","學(xué)生姓名");

da.TableMappings[0].ColumnMappings.Add("StudentPass","密碼");

da.TableMappings[0].ColumnMappings.Add("Sex","性別");

da.TableMappings[0].ColumnMappings.Add("BirthDay","生日");

da.TableMappings[0].ColumnMappings.Add("Email","郵件地址");

da.TableMappings[0].ColumnMappings.Add("Score","成績(jī)");

這樣在DataSource中的列名就被映射為后者。

DataSet版本
DataSet中,可以存在同一個(gè)DataRow的多個(gè)版本。它們由DataRowWVersion枚舉來(lái)指定。

– Current該行中包含當(dāng)前值。

– Default根據(jù)當(dāng)前DataRowState,為默認(rèn)行版本。

– Original該行中包含其原始值。

– Proposed該行中包含建議值。

DataRowVersion
版本在以下情況下發(fā)生更改:

在調(diào)用DataRow 對(duì)象的BeginEdit 方法之后,如果更改該值,則Current 和Proposed 值變得可用。

在調(diào)用DataRow 對(duì)象的CancelEdit 方法之后,Proposed 值將被刪除。

在調(diào)用DataRow 對(duì)象的EndEdit 方法之后,Proposed值變成Current 值。

在調(diào)用DataRow 對(duì)象的AcceptChanges 方法之后,Original 值變得與Current 值相同。

在調(diào)用DataTable 對(duì)象的AcceptChanges 方法之后,Original 值變得與Current 值相同。

在調(diào)用DataRow 對(duì)象的RejectChanges 之后,Proposed 值將被丟棄,版本變成Current。

 

如果對(duì) DataSet、DataTable 或 DataRow 調(diào)用 AcceptChanges,則將使 DataRow 的所有 Original 值都將被重寫為該 DataRow 的 Current 值。如果已修改將該行標(biāo)識(shí)為唯一行的字段值,那么當(dāng)調(diào)用 AcceptChanges 后,Original 值將不再匹配數(shù)據(jù)源中的值。

Fill方法的使用
默認(rèn)情況下,在使用DataAdapter的Fill方法時(shí),除了會(huì)填充DataSet之外,還會(huì)自動(dòng)調(diào)用DataSet.AcceptChanges。調(diào)用后所有行狀態(tài)中沒(méi)有任何行是“新改變的”。

對(duì)于某些情況,如希望從多個(gè)數(shù)據(jù)源填充一個(gè)DataSet,再將其寫回另外一個(gè)數(shù)據(jù)存儲(chǔ),這時(shí)要把DataAdapter的屬性AcceptChangesDuringFill設(shè)置為false,以便讓結(jié)果行表現(xiàn)為新添加的行。

 

[參考代碼]

//將指定的行Fill到SqlDataAdapter中

//0表示要Fill的行標(biāo) 1表示要Fill的行數(shù)

da.Fill(ds,0,1,"AuthorAndTitle");

Update方法
當(dāng)調(diào)用Update 方法時(shí),DataAdapter 將分析已作出的更改并執(zhí)行相應(yīng)的命令(INSERT、UPDATE 或DELETE)。當(dāng)DataAdapter 遇到對(duì)DataRow 的更改時(shí),它將使用InsertCommand、UpdateCommand 或DeleteCommand 來(lái)處理該更改。這樣,您就可以通過(guò)在設(shè)計(jì)時(shí)指定命令語(yǔ)法并在可能時(shí)通過(guò)使用存儲(chǔ)過(guò)程來(lái)盡量提高ADO.NET 應(yīng)用程序的性能。

在調(diào)用Update 之前,必須顯式設(shè)置這些命令。如果調(diào)用了Update 但不存在用于特定更新的相應(yīng)命令(例如,不存在用于已刪除行的DeleteCommand),則將引發(fā)異常。

[參考代碼]

SqlDataAdapter catDA = new SqlDataAdapter("SELECT * FROM Categories", nwindConn);      

catDA.UpdateCommand = new SqlCommand("UPDATE Categories SET CategoryName = @CategoryName " +"WHERE CategoryID = @CategoryID" , nwindConn);

catDA.UpdateCommand.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");

SqlParameter workParm = catDA.UpdateCommand.Parameters.Add("@CategoryID", SqlDbType.Int);

workParm.SourceColumn = "CategoryID";

//如果下面的不一致,說(shuō)明數(shù)據(jù)庫(kù)已經(jīng)更新了

workParm.SourceVersion = DataRowVersion.Original;

DataSet catDS = new DataSet();

catDA.Fill(catDS, "Categories");  

DataRow cRow = catDS.Tables["Categories"].Rows[0];

cRow["CategoryName"] = "NewName";

catDA.Update(catDS,"Categories");

 

MSDN上面的解釋:

1.       當(dāng)調(diào)用 Update 方法時(shí),DataAdapter 將分析已作出的更改并執(zhí)行相應(yīng)的命令(INSERT、UPDATE 或 DELETE)。當(dāng) DataAdapter 遇到對(duì) DataRow 的更改時(shí),它將使用 InsertCommand、UpdateCommand 或 DeleteCommand 來(lái)處理該更改。這樣,您就可以通過(guò)在設(shè)計(jì)時(shí)指定命令語(yǔ)法并在可能時(shí)通過(guò)使用存儲(chǔ)過(guò)程來(lái)盡量提高 ADO.NET 應(yīng)用程序的性能。在調(diào)用 Update 之前,必須顯式設(shè)置這些命令。如果調(diào)用了 Update 但不存在用于特定更新的相應(yīng)命令(例如,不存在用于已刪除行的 DeleteCommand),則將引發(fā)異常。

2.        請(qǐng)注意,在 UPDATE 語(yǔ)句的 WHERE 子句中指定的參數(shù)設(shè)置為使用 SourceColumn 的 Original 值。這一點(diǎn)很重要,因?yàn)?Current 值可能已被修改,并且可能不匹配數(shù)據(jù)源中的值。Original 值是曾用來(lái)從數(shù)據(jù)源填充 DataTable 的值。

3.        如果 SelectCommand 返回 OUTER JOIN 的結(jié)果,則 DataAdapter 不會(huì)為生成的 DataTable 設(shè)置 PrimaryKey 值。您必須自己定義 PrimaryKey 以確保正確解析重復(fù)行

CommandBuilder
如果DataTable 映射到單個(gè)數(shù)據(jù)庫(kù)表或從單個(gè)數(shù)據(jù)庫(kù)表生成,則可以利用CommandBuilder 對(duì)象自動(dòng)生成DataAdapter 的DeleteCommand、InsertCommand 和UpdateCommand。

       滿足以下條件,就可以使用CommandBuilder自動(dòng)生成命令

(1)       DataTable 映射到單個(gè)數(shù)據(jù)庫(kù)表或從單個(gè)數(shù)據(jù)庫(kù)表生成

(2)       必須使用了SelectCommand命令了,并有主建

為了生成INSERT、UPDATE 或DELETE語(yǔ)句,CommandBuilder 會(huì)自動(dòng)使用SelectCommand 屬性來(lái)檢索所需的元數(shù)據(jù)集。

 

[參考代碼]

SqlDataAdapter catDA = new SqlDataAdapter("SELECT * FROM Categories", nwindConn);      

catDA.InsertCommand = new SqlCommand("Insert into Categories(CategoryName,Description) values"+" (@CategoryName,@Description)", nwindConn);

catDA.InsertCommand.Parameters.Add("@CategoryName", SqlDbType.NVarChar, 15, "CategoryName");

catDA.InsertCommand.Parameters.Add("@Description", SqlDbType.NText, 16, "Description");

DataSet catDS = new DataSet();

catDA.Fill(catDS, "Categories");  

 

DataRow dr = catDS.Tables["Categories"].NewRow();

dr["CategoryName"] = "Added New Name";

dr["Description"] = "my Description";

catDS.Tables["Categories"].Rows.Add(dr);

 

catDA.Update(catDS,"Categories");

數(shù)據(jù)適配器的事件
OnRowUpdating:在數(shù)據(jù)行更新前執(zhí)行

OnRowUpdated:在數(shù)據(jù)行更新后執(zhí)行。其最佳用法是檢查單條更新語(yǔ)句的執(zhí)行結(jié)果。

 

SqlRowUpdatedEventArgs屬性

屬性
 描述
 
Command
 要執(zhí)行的數(shù)據(jù)命令
 
Errors
 錯(cuò)誤
 
Row
 要更新的行
 
StatementType
 要執(zhí)行的命令類型,可能為Select、Insert、Delete和Update
 
RecordsAffected
 要影響的行數(shù)
 
TableMapping
 更新所使用的DataTableMapping
 

 

[參考代碼]

myDataAdapter.RowUpdating += new SqlRowUpdatingEventHandler(MyUpdatingHandler);

//省略,OnRowUpdating主要用于在更新前判斷數(shù)據(jù)源是否已經(jīng)被其他客戶端更改

public void MyUpdatingHandler(object adapter,SqlRowUpdatingEventArgs e)

{

       switch(e.StatementType)

       {

              case StatementType.Update:

              {

                     SqlConnection myConnection = new SqlConnection( "server=(local);uid=sa;pwd=111;database=Pubs" );

                     string strSql = "Select * From Authors where au_fname='"

                                          +e.Row["au_fname",DataRowVersion.Original]+"'";

                     SqlCommand com = new SqlCommand(strSql,myConnection);

                     myConnection.Open();

                     if(com.ExecuteNonQuery()==0)

                     {

                            Response.Write("出錯(cuò)!有用戶已經(jīng)修改過(guò)數(shù)據(jù)集!");

                            e.Status = UpdateStatus.ErrorsOccurred;//報(bào)錯(cuò)

                     }

                     myConnection.Close();

                     break;

              }

       }

}

myDataAdapter.RowUpdated += new SqlRowUpdatedEventHandler(MyUpdatedHandler);

//省略,OnRowUpdated主要用于更新出錯(cuò)時(shí),是否忽略錯(cuò)誤繼續(xù)更新

public void MyUpdatedHandler(object adapter,SqlRowUpdatedEventArgs e)

{

switch(e.StatementType)

       {

       case StatementType.Update:

              if(e.Status==UpdateStatus.ErrorsOccurred)

              {

                                   e.Status = UpdateStatus.SkipCurrentRow;

                                   break;

                     }

              }

}

使用數(shù)據(jù)適配器最佳實(shí)踐
使用多個(gè)表填充一個(gè)DataSet
如果你是用批處理從多個(gè)表返回?cái)?shù)據(jù)并把這些數(shù)據(jù)填充到一個(gè)DataSet,fill方法將會(huì)使用第一個(gè)表的表名命名第一個(gè)表,以后的表命名將會(huì)采用在第一個(gè)表的表名基礎(chǔ)上加上一個(gè)遞增的數(shù)字。

SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Customers;SELECT * FROM Orders;", myConnection);

da.TableMappings.Add("Customers1", "Orders");

DataSet ds = new DataSet();

da.Fill(ds, "Customers");

避免自動(dòng)增量值沖突
DataSet 使您可標(biāo)識(shí)那些添加新行時(shí)自動(dòng)對(duì)其值進(jìn)行遞增的列。在DataSet 中使用自動(dòng)增量的列時(shí),如果自動(dòng)增量的列來(lái)自數(shù)據(jù)源,可避免添加到DataSet 的行和添加到數(shù)據(jù)源的行之間本地編號(hào)沖突。

例如一個(gè)表,它的主鍵列CustomerID 是自動(dòng)增量的。兩個(gè)新的客戶信息行添加到表中,并接收到自動(dòng)增量的CustomerID 值1 和2。然后,只有第二個(gè)客戶行被傳遞給DataAdapter 的方法Update,新添加的行在數(shù)據(jù)源接收到一個(gè)自動(dòng)增量的CustomerID 值1,與DataSet 中的值2 不匹配。當(dāng)DataAdapter 用返回值填充表中第二行時(shí),就會(huì)出現(xiàn)約束沖突,因?yàn)榈谝粋€(gè)客戶行已經(jīng)使用了CustomerID 值1。

要避免這種情況,建議把DataSet 中的列創(chuàng)建為AutoIncrementStep 值等于-1 并且AutoIncrementSeed 值等于0,另外,還要確保數(shù)據(jù)源生

成的自動(dòng)增量標(biāo)識(shí)值從1 開(kāi)始,并且以正階值遞增。

CommandBuilder 的使用
在設(shè)計(jì)階段不要使用CommandBuilder,否者產(chǎn)生DataAdapter Command屬性的進(jìn)程將會(huì)受到干擾。? CommandBuilder使用SelectCommand決定其他Command屬性的值。如果DataAdapter的SelectCommand本身發(fā)生變化,應(yīng)該使用RefreshSchema去刷新Command的屬性。

只要DataAdapter的Command屬性為空,CommandBuilder就僅僅創(chuàng)建一個(gè)Command,即使你明確地指定Command的屬性值,CommandBuilder也不會(huì)重寫,所以如果你想創(chuàng)建一個(gè)Command并保留以前的屬性設(shè)置,那么就把Command的屬性設(shè)置為null。

QA
Q: 適配器事件的例子,應(yīng)該是更新前查看是否有其他的用戶已修改了"數(shù)據(jù)庫(kù)",而不是"數(shù)據(jù)集"吧?

A:對(duì),是數(shù)據(jù)庫(kù)。

 

Q:在智能客戶端中,有多個(gè)客戶端對(duì)服務(wù)器端上的數(shù)據(jù)進(jìn)行增、刪、改操作,客戶端可以脫機(jī)進(jìn)行操作,通過(guò)計(jì)時(shí)器與服務(wù)器同步數(shù)據(jù) 在一個(gè)客戶端上怎樣把別的客戶端刪除的記錄同步到本地呢?

A:建議把客戶端用戶對(duì)服務(wù)器數(shù)據(jù)庫(kù)中的刪除不做真正刪除,只是做刪除標(biāo)記。這樣就可以把它同步到本地了。

 

Q: 在更新表時(shí)出錯(cuò),是否是因?yàn)楸桓碌谋頉](méi)有設(shè)置主鍵?

A:對(duì)。通常情況如果沒(méi)有設(shè)置主鍵,會(huì)更新失敗。

 

Q: DataSet有多行(n行)需要被更新時(shí),調(diào)用DataAdapter的Update方法后,RowUpdated事件,是觸發(fā)一次,還是觸發(fā)多次(n次)?

A:觸發(fā)n次,每更新一行都觸發(fā)。

 

Q: DataAdapter中的Command似乎不是很靈活(我是指只能寫死在代碼嗎?),我是想,能不能通過(guò)配置文件來(lái)?這樣會(huì)比較靈活!

A:可以把他寫到XML文件中,讀入XML文件,得到對(duì)應(yīng)的Command,也是可以的。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
[C#]使用DataSet Datatable 更新數(shù)據(jù)庫(kù)的三種方式
[轉(zhuǎn)帖]ADO.net中適配器DataAdapter的說(shuō)明
先利用DataSet更改數(shù)據(jù),再將更改保存到數(shù)據(jù)庫(kù)中
ADO.NET對(duì)象模型 - 技術(shù)改變世界!學(xué)習(xí)改變自己! - 博客園
DataSet與DataReader的區(qū)別解讀
ADO.NET中的五個(gè)主要對(duì)象 - 激情 希望 斗志昂揚(yáng) - 博客園
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服