從LINQ to SQL的"一行更新法"聊起

我喜歡LINQ to SQL的簡潔,就拿更新資料庫某筆資料這件事來說,你可以忘記SqlConnection、丟掉SqlCommand、抛下SqlParameter,就搞定整個更新動作,對寫慣ADO.NET的人來說,實在是件不可思議的事。

像下面這個例子,寫一段LINQ配上Single()取得資料物件,重新指定值,然後SubmitChanges()就完成了ID=2 Player資料的CreateTime欄位更新。有種袖子都還沒捲起來,敵人就忽然自已暴斃的莫名爽快。

    protected void Page_Load(object sender, EventArgs e)
    {
        PlaygroundDataClassesDataContext db = 
            new PlaygroundDataClassesDataContext();
        db.Log = new DebuggerWriter();
        (from o in db.Players where o.ID == 2 select o)
            .Single().CreateTime = DateTime.Now;
        db.SubmitChanges();
    }

上回既然提過DebuggerWriter,我們就不該只知其然不知其所以然,來看看背後發生什麼事吧!

這裡發生了兩個SQL動作,在Single()時會SELECT取回ID=2的資料,而SubmitChages()則進行UPDATE動作。值得一提的是,在UPDATE時,除了ID=2,它還會一併比較Name及CreateTime,用意是確認資料讀出到更新這段期間資料沒有被其他人更動過,防止多人同時更新資料庫時發生彼此資料互相覆寫衝突。

要印證它的保護效果,我們可以在db.SubmitChanges()上設定中斷點,讓VS2008跑偵錯模式停在該中斷點上,此時另外開SQL Server Management Studio執行T-SQL更新ID=2的資料:

UPDATE Player SET CreateTime = '2009-07-08 12:34:56'
WHERE ID = 2

接著好戲上場,在VS2008按下F10執行db.SubmitChanges(),會發生以下例外:

System.Data.Linq.ChangeConflictException: Row not found or changed. (中文版為: 資料列找不到,或者已變更。)

這個實驗證實了LINQ to SQL的確有提供資料庫更新時的衝突管理,然而要如何妥善處理更新衝突是門學問,保哥有篇文章做了進一步的剖析,推薦給大家參考。

當然,如果效能不是最優先考量,我還有一招。以前介紹過可在LINQ to SQL上使用的TransactionScope大法,在Single()到SubmitChanges()間對資料上鎖,防止別人擅動,就不會有衝突的問題(但想其他要更新資料的人會被卡住,直到這一方的UPDATE完成為止)。在此還是要善盡提醒之責,包TransactionScope的方法較適合更新頻率不高、鎖定時間不長、使用人數不多的情境,採用前宜審慎評估,不然有可能大幅拖累系統整體效能。

    protected void Page_Load(object sender, EventArgs e)
    {
        using (System.Transactions.TransactionScope tx
            = new System.Transactions.TransactionScope())
        {
            PlaygroundDataClassesDataContext db =
                new PlaygroundDataClassesDataContext();
            db.Log = new DebuggerWriter();
            (from o in db.Players where o.ID == 2 select o)
                .Single().CreateTime = DateTime.Now;
            db.SubmitChanges();
        }
    }
歡迎推文分享:
Published 14 July 2009 02:58 AM 由 Jeffrey
Filed under: ,
Views: 13,175



意見

沒有意見

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<July 2009>
SunMonTueWedThuFriSat
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication