目錄
【十天學會Linq to sql】第一天—–基礎知識
【十天學會Linq to sql】第二天—–資料內容
【十天學會Linq to sql】第三天—–資料查詢
【十天學會Linq to sql】第四天—–資料更新
【十天學會Linq to sql】第六天——預存程序
歡迎大家繼續關注CoolHots技術分享;你們的支援就是我更新的動力!
這一篇,主要教的是使用Linq to sql進行資料更新和更新衝突的解決方案;資料庫還是以上一篇文章的Students資料庫進行教學;
一、單條記錄更新
使用Linq to Sql來進行Update,執行的步驟:擷取一個記錄-〉更新欄位 -〉submitChanges();
//單條記錄更新// 首先從資料內容擷取一條記錄 var Update1 = db.Students.Single(n => n.StudentName == "CoolHots"); //先輸出更新前的資料 Console.WriteLine("更新前CoolHots的StudentNo為: "+Update1.StudentNo); //改變學生CoolHots的StudentNo,其他不需要更新的不需要賦值; Update1.StudentNo = "123456"; //提交資料到資料庫 db.SubmitChanges(); //下面把更新後的資料輸出來 Update1 = db.Students.Single(n => n.StudentName == "CoolHots"); Console.WriteLine("更新後CoolHots的StudentNo為: " + Update1.StudentNo);
通過控制台輸出,可以看到資料的確已經更新成功了
現在,把調用SubmitChanges方法放在最後,看看會出現神馬情況:
//單條記錄更新// 首先從資料內容擷取一條記錄var Update1 = db.Students.Single(n => n.StudentName == "CoolHots");//先輸出更新前的資料Console.WriteLine("更新前CoolHots的StudentNo為: " + Update1.StudentNo); //改變學生CoolHots的StudentNo,其他不需要更新的不需要賦值;Update1.StudentNo = "123456";//提交資料到資料庫 //下面把更新後的資料輸出來Update1 = db.Students.Single(n => n.StudentName == "CoolHots");Console.WriteLine("更新後CoolHots的StudentNo為: " + Update1.StudentNo); db.SubmitChanges();
控制台的輸出為:
現在是不是看到在資料更新之前,資料庫中的資料還沒有改變,但是代碼查詢出來的資料已經變化了,很奇怪嗎?難道是Bug?
其實原因是Identity Cache搞出來的問題,DataContext以主鍵為key對資料對象進行緩衝以此對資料對象的生命週期進行跟蹤。藉助Sql profile可以發現,第二次調用db.Students.Single時,資料庫並沒有查詢的記錄,這裡DataContext直接在記憶體中尋找該對象並且返回。當然也可以關閉這種機制,只需要調用ctx.ObjectTrackingEnabled = false。DataContext就不再對資料對象進行Identity Cache,每次查詢結果都是通過查詢資料庫得到。
所以一般來說在資料需要更新的時候馬上就需要查詢的話還是先提交一次資料比較穩妥;
二、批次更新
微軟提供的例子;
先看一下更新之前資料庫裡面的資料;
然後再通過Linq to sql 批次更新
//批次更新//先擷取List資料var Updates = db.Students.Where(n => n.Address == "廣西經貿職業技術學院");//通過遍曆來修改資料foreach (var Update in Updates){ Update.Address = "廣西經貿職業技術學院資訊工程系";}//提交資料到資料庫db.SubmitChanges();
我們來查看一下更新後的資料
這種方法必須要查詢出要更新的資料,確實有點不雅,也是Linq To SQL 略顯尷尬的一面。所以我再後面的文章裡面再進行擴充,這裡是最基礎的操作,暫時不擴充那麼多。
三、更新衝突的解決方案
資料庫資料更新通常會遇到同步衝突的問題,比如獲得資料以後,對資料進行一系列的操作,然後把新的資料更新回資料庫。如果在資料進行操作的同時,有其它程式改動了該資料的值,這樣就會發生衝突。到底資料是應該保留現有的值呢還是把改動的值強行更新到資料庫呢?Linq to SQL提供了很多方法來解決這種衝突問題。
我們來試一下簡單的更新代碼:
我們在 db.SubmitChanges();斷點;
var Update1 = db.Students.Single(n => n.StudentName == "CoolHots");Update1.StudentNo = "123456";db.SubmitChanges();
在執行到db.SubmitChanges()的時候,我們手動在SQL Server Management Studio裡面修改了資料StudentNo;然後回到VS2010繼續執行;這時會拋出ChangeConflictException,提示該行記錄找不到或已經更改了;
這個問題,還是有好兩種辦法解決的;
1、在映射欄位的Column Attribute中添加UpdateCheck屬性
UpdateCheck的意思是在更新的時候是否檢查衝突,分為三種,根據自己的需求進行選擇:
Always 始終檢查
Never 從不檢查
WhenChanged 當資料有改動的時候檢查
2. 使用ObjectChangeConflict的Resolve方法,比如:
var Update1 = db.Students.Single(n => n.StudentName == "CoolHots");Update1.StudentNo = "123456"; db.SubmitChanges();try{ db.SubmitChanges();}catch (ChangeConflictException){ foreach (ObjectChangeConflict confict in db.ChangeConflicts) { confict.Resolve(RefreshMode.KeepCurrentValues); }}finally{ db.SubmitChanges();}
這裡RefreshMode就是表示解決衝突的方法,也有三種:
KeepChanges 把改變過的屬性值更新到資料庫,沒有改變過的屬性值就用資料庫的當前值
KeepCurrentValues 把當前所有值更新到資料庫
OverwriteCurrentValues 使用資料庫的當前值,不做強行更新
謝了一個多小時,第三篇文章寫完了。
感謝大家對我的支援;你們的支援是我繼續寫下去的動力;
如果有任何疑問,可以到CoolHots技術分享QQ群:60710954進行交流;
接下來打算同步發布MVC基礎教程;和Linq to sql一起結合使用;當然,這來你哥哥教程並不是說結合起來寫,而是相互關聯。在MVC裡面試用Linq來進行訪問資料庫;
MVC教程最遲到明天晚上發第一篇出來;
個人首頁:
本文由CoolHots原創編譯,轉載請保留本文連結
個人首頁:CoolHots技術分享