Linq to Sql學習總結5
阿新 • • 發佈:2018-11-20
修改併發異常ChangeConfictException
//測試修改併發異常ChangeConfictException var query = from p in ctx.Products where p.CategoryID == 1 select p; foreach (var p in query) { p.UnitsInStock = Convert.ToInt16(p.UnitsInStock - 1); } ctx.SubmitChanges();// 在這裡設斷點,程式執行到此處時,在資料庫執行如下T_SQL操作 /* UPDATE dbo.Products SET UnitsInStock = UnitsInStock - 2 WHERE CategoryID=1 */ //然後繼續執行程式,會丟擲修改併發異常ChangeConfictException /* 原因分析:當客戶端提交的修改物件自讀取之後已經在資料庫中發生改動,就產生了修改併發。*/ /*不考慮併發修改異常設定:實體類屬性column特性增加UpdateCheck = UpdateCheck.Never * 不考慮併發修改異常情況下,預設是最後一次更新起作用 */
處理修改併發異常ChangeConfictException
//處理修改併發異常ChangeConfictException var query = from p in ctx.Products where p.ProductID == 1 selectp; foreach (var p in query) { p.UnitsInStock = Convert.ToInt16(p.UnitsInStock - 1); } try { ctx.SubmitChanges(ConflictMode.ContinueOnConflict); } catch (ChangeConflictException) { foreach (ObjectChangeConflict cc in ctx.ChangeConflicts) { Products product = (Products)cc.Object; cc.Resolve(RefreshMode.OverwriteCurrentValues);// 放棄當前程序更新,所有更新以原先其它程序更新為準 //cc.Resolve(RefreshMode.KeepCurrentValues); // 放棄原先其它程序更新,所有更新以當前程序更新為準 //cc.Resolve(RefreshMode.KeepChanges); // 原先其它程序更新有效,衝突欄位以當前程序更新為準 } } ctx.SubmitChanges();
//針對不同策略處理不同欄位修改併發異常ChangeConfictException var query = from p in ctx.Products where p.ProductID == 1 select p; foreach (var p in query) { p.UnitsInStock = Convert.ToInt16(p.UnitsInStock - 1); } try { ctx.SubmitChanges(ConflictMode.ContinueOnConflict); } catch (ChangeConflictException) { //遍歷併發衝突物件集合 foreach (ObjectChangeConflict cc in ctx.ChangeConflicts) { //遍歷當前衝突物件更新失敗的成員(即更新失敗的列) foreach (MemberChangeConflict mc in cc.MemberConflicts) { if (mc.Member.Name == "UnitsInStock") { mc.Resolve(RefreshMode.KeepCurrentValues); // 放棄原先其它程序更新,所有更新以當前程序更新為準 } else if (mc.Member.Name == "UnitPrice") { mc.Resolve(RefreshMode.OverwriteCurrentValues); // 放棄當前程序更新,所有更新以原先其它程序更新為準 } else { mc.Resolve(RefreshMode.KeepChanges); // 原先其它程序更新有效,衝突欄位以當前程序更新為準 } } } } ctx.SubmitChanges();
事務:
//Linq to sql在提交更新的時候預設會建立事務,一部分修改發生錯誤的話其它修改也不會生效: //假設資料庫中已經存在顧客ID為“ALFKI”的記錄,那麼第二次插入操作失敗將會導致第一次的插入操作失效。 ctx.Customers.InsertOnSubmit(new Customers { CustomerID = "abcdf", CompanyName = "zhuye" }); ctx.Customers.InsertOnSubmit(new Customers { CustomerID = "ALFKI", CompanyName = "zhuye" }); ctx.SubmitChanges();
使用事務
ctx.Connection.Open(); ctx.Transaction = ctx.Connection.BeginTransaction(); ctx.Customers.InsertOnSubmit(new Customers { CustomerID = "abcdf", CompanyName = "zhuye" }); ctx.Customers.InsertOnSubmit(new Customers { CustomerID = "ALFKI", CompanyName = "zhuye" }); try { ctx.SubmitChanges(); ctx.Transaction.Commit(); } catch { ctx.Transaction.Rollback(); } ctx.Connection.Close();
使用TransactionScope
using (TransactionScope tranScope = new TransactionScope()) { ctx.Customers.InsertOnSubmit(new Customers { CustomerID = "abcdf", CompanyName = "zhuye" }); ctx.Customers.InsertOnSubmit(new Customers { CustomerID = "ALFKI", CompanyName = "zhuye" }); tranScope.Complete(); }