日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

    歡迎訪問 生活随笔!

    生活随笔

    當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

    编程问答

    ef 并发控制

    發布時間:2023/12/9 编程问答 23 豆豆
    生活随笔 收集整理的這篇文章主要介紹了 ef 并发控制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
    ef 并發控制

    ef 并發控制

    什么是并發? 并發分悲觀并發和樂觀并發。 悲觀并發:比如有兩個用戶A,B,同時登錄系統修改一個文檔,如果A先進入修改,則系統會把該文檔鎖住,B就沒辦法打開了,只有等A修改完,完全退出的時候B才能進入修改。 樂觀并發:同上面的例子,A,B兩個用戶同時登錄,如果A先進入修改緊跟著B也進入了。A修改文檔的同時B也在修改。如果在A保存之后B再保存他的修改,此時系統檢測到數據庫中文檔記錄與B剛進入時不一致,B保存時會拋出異常,修改失敗。 EF中如何控制并發? Entity Framework不支持悲觀并發,只支持樂觀并發。 如果要對某一個表做并發處理,就在該表中加一條Timestamp類型的字段。注意,一張表中只能有一個Timestamp的字段。 Data Annotations中用Timestamp來標識設置并發控制字段,標識為Timestamp的字段必需為byte[]類型。 publicclass Person { public int PersonId { get; set; } public int SocialSecurityNumber { get; set; } public string FirstName { get; set; } public string LastName { get; set; } 1702133471 public byte[] RowVersion { get; set; } } Fluent API用IsRowVersion方法 modelBuilder.Entity<Person>().Property(p => p.RowVersion).IsRowVersion(); 我們看到生成的數據庫中,RowVersion是timestamp類型。 下面我們寫一段代碼來測試一下: staticvoid Main(string[] args) { var person = new Person { FirstName = "Rowan", LastName = "Miller", SocialSecurityNumber = 12345678 }; //新增一條記錄,保存到數據庫中using (var con = new BreakAwayContext()) { con.People.Add(person); con.SaveChanges(); } var firContext = new BreakAwayContext(); //取第一條記錄,并修改一個字段:這里是修改了FirstName //先不保存var p1 = firContext.People.FirstOrDefault(); p1.FirstName = "Steven"; //再創建一個Context,同樣取第一條記錄,修改LastName字段并保存using (var secContext = new BreakAwayContext()) { var p2 = secContext.People.FirstOrDefault(); p2.LastName = "Francis"; secContext.SaveChanges(); } try { firContext.SaveChanges(); Console.WriteLine(" 保存成功"); } catch (DbUpdateConcurrencyException ex) { Console.WriteLine(ex.Entries.First().Entity.GetType().Name + " 保存失敗"); } Console.Read(); } 上面我們實例化了三個DbContext,第一個增加一條記錄到數據庫中,第二個修改剛增加的記錄但不保存,然后第三個Context也取剛新增的記錄并保存,最后再保存第二個Context,結果保存失敗。 可以看到我們的并發控制取到了作用。 分析EF生成的SQL語句: exec sp_executesql N'update [dbo].[People] set [LastName] = @0 where (([PersonId] = @1) and ([RowVersion] = @2)) select [RowVersion] from [dbo].[People] where @@ROWCOUNT > 0 and [PersonId] = @1',N'@0 nvarchar(max) ,@1 int,@2 binary(8)',@0=N'Francis',@1=1,@2=0x00000000000007D1 可以看到,它在取對應記錄的時候把RowVersion也作為篩選條件。上面例子中的secContext保存的時候,數據庫中的RowVersion字段的值就變了,所以firContext保存的時候用原來的RowVersion取值,自然就取不到相應的記錄而報錯。 如果我們只是要對某個字段作并發控制呢?別著急,EF也有辦法。 Data Annotations中用ConcurrencyCheck來標識 public class Person { publicint PersonId { get; set; } [ConcurrencyCheck] public int SocialSecurityNumber { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public byte[] RowVersion { get; set; } } Fluent API用IsConcurrencyToken方法 modelBuilder.Entity<Person>().Property(p => p.SocialSecurityNumber).IsConcurrencyToken(); 上面的實體中,我們將SocialSecurityNumber(社會保險號)標識為開放式并發,也寫一個類似的代碼測試一下: staticvoid Main(string[] args) { var person = new Person { FirstName = "Rowan", LastName = "Miller", SocialSecurityNumber = 12345678 }; //新增一條記錄,保存到數據庫中using (var con = new BreakAwayContext()) { con.People.Add(person); con.SaveChanges(); } var firContext = new BreakAwayContext(); //取第一條記錄,并修改SocialSecurityNumber字段 //先不保存var p1 = firContext.People.FirstOrDefault(); p1.SocialSecurityNumber = 123; //再創建一個Context,同樣取第一條記錄, //修改SocialSecurityNumber字段并保存using (var secContext = new BreakAwayContext()) { var p2 = secContext.People.FirstOrDefault(); p2.SocialSecurityNumber = 456; secContext.SaveChanges(); } try { firContext.SaveChanges(); Console.WriteLine(" 保存成功"); } catch (DbUpdateConcurrencyException ex) { Console.WriteLine(ex.Entries.First().Entity.GetType().Name + " 保存失敗"); } Console.Read(); } 運行結果同樣是保存失敗,說明我們的并發控制起作用了。 分析一下EF執行的SQL: exec sp_executesql N'update [dbo].[People] set [SocialSecurityNumber] = @0 where (([PersonId] = @1) and ([SocialSecurityNumber] = @2)) ',N'@0 int,@1 int,@2 int',@0=123,@1=1,@2=12345678 可以看到,EF將我們要并發控制的列SocialSecurityNumber也作為一個篩選條件,這樣firContext保存的時候也會因為的數據庫中SocialSecurityNumber值變了,取不到對應的記錄而更新失敗。 補充一下:如果是EDMX如何將字段設置為Concurrency。很簡單,在對應的字段上右鍵-屬性。在打開的屬性窗口中有一個并發模式,你將它選擇為Fixed即可。 posted on 2018-08-10 22:45 micwin 閱讀(...) 評論(...) ?編輯 收藏

    轉載于:https://www.cnblogs.com/chinanetwind/articles/9457873.html

    總結

    以上是生活随笔為你收集整理的ef 并发控制的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。