透過vs.net資料表單嚮導看Ado.net

來源:互聯網
上載者:User
ado|資料 透過vs.net資料表單嚮導看Ado.net

鄭佐2005-1-1

在csdn上經常碰到有人問一些Ado.net的問題,特別是開發資訊管理系統之類的跟資料庫比較密切的程式時,在資料和介面層的開發中會遇到不少常見問題,下面我們通過vs.net內建的資料表單嚮導來看看能它能幫我們決絕什麼問題。



一.使用嚮導

建立Windows 應用程式,為當前項目添加組件,選擇資料表單嚮導,這裡名稱填寫為DataForm1.cs。單擊開啟出現資料表單嚮導對話方塊。建立新的類型化資料集MyDataSet。使用本機資料取得連線精靈,這裡我選擇Northwind庫作為資料來源。在選擇表或視圖那一步添加Categories表和Products表。添加一個表之間的關係取名CategoryProductRel。在選擇顯示樣式一步中選擇顯示資料的方式為單個控制項中的單個記錄,這個就會有資料繫結到文字框。可以用資料導航來選擇父表的記錄。嚮導完成後會產生一個OleDbConnection,幾個表產生幾個OleDbDataAdapter負責資料的擷取和更新。另外就是一個強型別的資料集。

整個程式的運行介面如下:



準系統都包括了,不過等你點擊幾下,程式介面上就會出現小的bug,微軟可能也估計到沒有人會要這個表單來處理資料,不過這個不是我們所關心的。



二.資料填充

先來看看資料集結構:



一個Categories表作為父表,Products表作為子表,CategoryID為外鍵,建立的資料表關係。

通過載入按鈕資料庫中的相關資料會被填充到資料集。執行的LoadDataSet()方法的過程如下:

使用DataAdatpter.Fill()方法填充資料到臨時的一個資料集,如果操作成功,將合并這個臨時資料集到原有的資料集,DataGrid通過表關係綁定子表。

// 嘗試填充臨時資料集。

this.FillDataSet(objDataSetTemp);

grdProducts.DataSource = null;

// 清空資料集中的舊記錄。

objMyDataSet.Clear();

// 將記錄合并到主要資料集中。

objMyDataSet.Merge(objDataSetTemp);

grdProducts.SetDataBinding(objMyDataSet, "Categories.CategoryProductRel");

在資料填充的方法中我們注意到

dataSet.EnforceConstraints = false;

這一步會對資料填充效率會有所提高。

另外還有一個細節就是執行兩個以上DataAdapter的資料存取方法時顯式開啟關閉資料連線效率會比較高。因為在執行DataAdapter的資料更新方法前和方法後資料連線Connection執行個體的狀態不會改變。如果下面代碼。

//this.oleDbConnection1.Open();

this.oleDbDataAdapter1.Fill(dataSet);

this.oleDbDataAdapter2.Fill(dataSet);

執行之前Connection的狀態是關閉的,那可想而知這一過程會執行兩次開啟串連關閉串連。

其實一次就夠。

為了資料的嚴密性,填充完資料後不要忘了加上下面代碼,

// 重新開啟約束檢查。

dataSet.EnforceConstraints = true;

如果是直讀那就無所謂了。

有了資料填充那就來看資料的單值綁定和多值綁定。



三.資料繫結

資料的單值綁定如下:

this.editCategoryID.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.objMyDataSet, "Categories.CategoryID"));

this.editCategoryName.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.objMyDataSet, "Categories.CategoryName"));

上面一段代碼把資料表的資料行繫結到了TextBox的Text屬性上。

資料的多值綁定如下:

grdProducts.SetDataBinding(objMyDataSet, "Categories.CategoryProductRel");

可見通過關係綁定資料相當方便。



四.資料瀏覽

這裡通過BindingContext對象的索引得到BindingManagerBase執行個體,而BindingManagerBase.Position就是我們需要的,通過Position來顯示某一行的資料記錄。

例如下一條:

this.BindingContext[objMyDataSet,"Categories"].Position = (this.BindingContext[objMyDataSet,"Categories"].Position + 1);

最後一條:

this.BindingContext[objMyDataSet,"Categories"].Position = (this.objMyDataSet.Tables["Categories"].Rows.Count - 1);

另外調用PositionChanged()方法來改變導覽按鈕之間的索引顯示。



五.資料編輯

從添加方法中我們可以看到下面代碼:

// 清除當前編輯內容

this.BindingContext[objMyDataSet,"Categories"].EndCurrentEdit();

經常有人在csdn上提問為什麼在編輯DataGrid或TextBox的時候,只有當編輯框失去焦點的時候才會被儲存。要實現不改變焦點就儲存可以通過上面代碼實現。

相對應的取消如下:

this.BindingContext[objMyDataSet,"Categories"].CancelCurrentEdit();

刪除資料的代碼如下:

this.BindingContext[objMyDataSet,"Categories"].RemoveAt(this.BindingContext[objMyDataSet,"Categories"].Position);

看到上面代碼發現原來資料不是真正的在資料來源刪除,不過我們開發的時候可能用的更多的是DataRow的Delete()方法,這樣能夠提交資料更新到資料來源。



六.資料更新

嚮導產生的程式碼如下:

public void UpdateDataSet()

{

// 建立一個新資料集來儲存對主要資料集所做的更改。

WindowsApplication1.MyDataSet objDataSetChanges = new WindowsApplication1.MyDataSet();

// 停止當前的任何編輯。

this.BindingContext[objMyDataSet,"Categories"].EndCurrentEdit();

this.BindingContext[objMyDataSet,"Products"].EndCurrentEdit();

// 擷取對主要資料集所做的更改。

objDataSetChanges = ((WindowsApplication1.MyDataSet)(objMyDataSet.GetChanges()));

// 檢查是否做了任何更改。

if ((objDataSetChanges != null))

{

try

{

// 需要做一些更改,所以嘗試通過調用 update 方法

// 和傳遞資料集以及任何參數來更新資料來源。

this.UpdateDataSource(objDataSetChanges);

objMyDataSet.Merge(objDataSetChanges);

objMyDataSet.AcceptChanges();

}

catch (System.Exception eUpdate)

{

// 在此處添加錯誤處理代碼。

throw eUpdate;

}

// 添加代碼以檢查返回的資料集中是否有任何可能已被

// 推入到行對象錯誤中的錯誤。

}

}

更新過程很經典,通過擷取修改過的資料集更新子集提交到資料來源完成更新動作,接著合并子集到原有資料集,順便提一下,合并的過程是基於資料表主鍵來判斷的。通過調用DataSet.AcceptChanges()方法提交自載入此 DataSet 或上次調用 AcceptChanges 以來對 DataSet 進行的所有更改。對應的就是Data.RejectChanges();復原自建立 DataSet 以來或上次調用 DataSet.AcceptChanges 以來對 DataSet 進行的所有更改。



七.補充

對於資料的更新需要視程式環境而定,不能都通過擷取子集再合并的方法,具體請看ADO.NET中的多資料表操作淺析—修改一文。也有人問起怎樣實現這樣的功能:在資料庫中的某一個欄位資料為0或1,而在程式顯示上想讓它顯示為是或否,這裡我認為最好不要在Sql語句上做文章,代替的方法就是使用Binding對象的Format 事件和Parse事件。Binding.Format 事件,當將某控制項的屬性綁定到某個資料值時發生。Binding.Parse 事件,在資料繫結控制項的值更改時發生。還有可以通過BindingManagerBase.PositionChanged事件來設定各個按鈕的狀態。需要具體的例子可以看MSDN或《Ado.net Core Reference》一書。另外,使用Try{}catch (System.Exception ex){}還是要視情況而定,不能一味的全都通過Exception基類把什麼都撲捉了,如果知道有可能會拋出什麼類型的異常,還是越具體越好,造成的反面效果就是要寫更多的代碼。具體為什麼要這麼做可以看《Applied Microsoft.NET Framework Programming》一書。





相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。