<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      02-EF Core筆記之保存數據

      EF Core通過ChangeTracker跟蹤需要寫入數據庫的更改,當需要保存數據時,調用DbContext的SaveChanges方法完成保存。

      基本的添加、更新、刪除操作示例如下:

      using (var context = new BloggingContext())
      {
          // seeding database
          context.Blogs.Add(new Blog { Url = "http://sample.com/blog" });
          context.Blogs.Add(new Blog { Url = "http://sample.com/another_blog" });
          context.SaveChanges();
      }
      
      using (var context = new BloggingContext())
      {
          // add
          context.Blogs.Add(new Blog { Url = "http://sample.com/blog_one" });
          context.Blogs.Add(new Blog { Url = "http://sample.com/blog_two" });
      
          // update
          var firstBlog = context.Blogs.First();
          firstBlog.Url = "";
      
          // remove
          var lastBlog = context.Blogs.Last();
          context.Blogs.Remove(lastBlog);
      
          context.SaveChanges();
      }
      

      關聯數據

      在EF Core中,除了獨立的模型外,還有與模型關聯的數據,這部分數據通過獨立模型添加到模型中,在SaveChanges時將會持久化到數據庫中。例如:

      using (var context = new BloggingContext())
      {
          var blog = new Blog
          {
              Url = "http://blogs.msdn.com/dotnet",
              Posts = new List<Post>
              {
                  new Post { Title = "Intro to C#" },
                  new Post { Title = "Intro to VB.NET" },
                  new Post { Title = "Intro to F#" }
              }
          };
      
          context.Blogs.Add(blog);
          context.SaveChanges();
      }
      

      在這段代碼中,Blog對象和三個Post對象將會被持久化。

      如果要更改關系的引用,可將Post對象中的Blog引用設置為其它Blog對象即可:

      using (var context = new BloggingContext())
      {
          var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" };
          var post = context.Posts.First();
      
          post.Blog = blog;
          context.SaveChanges();
      }
      

      如果要刪除關系,只需將Post對象中的Blog引用設置為null即可,此時EF Core將判斷是否為必須關系,如果為必須關系,則從數據庫中刪除Post對象,如果為非必須關系,則將數據庫中對應的外鍵設置為null。

      級聯刪除

      級聯刪除是數據庫的概念,意思是當主體被刪除時,所有依賴該主體的項(通過外鍵關聯)也會被自動刪除。

      EF Core對于提供了更細粒度的管理,它允許我們定義刪除行為,來控制依賴關系被移除時,如何處理關系的子實體。需要注意的是,EF Core的刪除行為僅對已加載的數據生效,如果關系未加載到內存中,則超出了EF Core的管控范圍。

      事務

      事務允許以原子方式處理多個數據庫操作。 如果已提交事務,則所有操作都會成功應用到數據庫。 如果已回滾事務,則所有操作都不會應用到數據庫。

      默認情況下,每次SaveChanges方法的所保存的所有更改都將在一個事務中,要么全部保存成功,要么全部保存失敗。此種情況已能滿足大多數應用的需要。

      共享事務(通過共享連接實現)

      共享事務僅對關系型數據庫有效,因為此機制用到了DbConnection和DbTransaction。要實現該機制,首先要在多個DbContext之間共享數據庫連接。

      以下代碼演示了如何共享數據庫連接:

      public class BloggingContext : DbContext
      {
          private DbConnection _connection;
      
          public BloggingContext(DbConnection connection)
          {
            _connection = connection;
          }
      
          public DbSet<Blog> Blogs { get; set; }
      
          protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
          {
              optionsBuilder.UseSqlServer(_connection);
          }
      }
      

      對于上面代碼中的BloggingContext,可以先創建DbConnection來進行實例化,也可以通過DbTransaction獲取DbConnection來實例化。隨后即可在同一個DbConnection上共享事務了。

      使用 System.Transactions(環境事物)

      如果需要跨較大作用域進行協調,則可以使用環境事務。例如:

      using (var scope = new TransactionScope(
          TransactionScopeOption.Required,
          new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted }))
      {
          using (var connection = new SqlConnection(connectionString))
          {
              connection.Open();
      
              try
              {
                  // Run raw ADO.NET command in the transaction
                  var command = connection.CreateCommand();
                  command.CommandText = "DELETE FROM dbo.Blogs";
                  command.ExecuteNonQuery();
      
                  // Run an EF Core command in the transaction
                  var options = new DbContextOptionsBuilder<BloggingContext>()
                      .UseSqlServer(connection)
                      .Options;
      
                  using (var context = new BloggingContext(options))
                  {
                      context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
                      context.SaveChanges();
                  }
      
                  // Commit transaction if all commands succeed, transaction will auto-rollback
                  // when disposed if either commands fails
                  scope.Complete();
              }
              catch (System.Exception)
              {
                  // TODO: Handle failure
              }
          }
      }
      

      顯示登記到環境事務中:

      context.Database.EnlistTransaction(transaction);
      

      使用環境事務前,需驗證使用的提供程序是否支持環境事務。

      并發控制

      數據庫并發指多個進程或用戶同時訪問或更改數據庫中的相同數據的情況。 并發控制指的是用于在發生并發更改時確保數據一致性的特定機制。

      EF Core采用樂觀并發控制來解決并發沖突問題。工作原理:每當在 SaveChanges 期間執行更新或刪除操作時,會將數據庫上的并發令牌值與通過 EF Core 讀取的原始值進行比較。如果一致則可以完成操作,如果不一致,則終止事務。

      在關系數據庫上,EF Core 會對任何 UPDATE 或 DELETE 語句的 WHERE 子句中的并發令牌值進行檢查。 執行這些語句后,EF Core 會讀取受影響的行數。如果未影響任何行,將檢測到并發沖突,并且 EF Core 會引發 DbUpdateConcurrencyException。

      在檢測到并發沖突后,EF Core會引發DbUpdateConcurrencyException異常,該異常中提供了一些有用的參數來幫助我們解決沖突:

      • “當前值”是應用程序嘗試寫入數據庫的值。
      • “原始值”是在進行任何編輯之前最初從數據庫中檢索的值。
      • “數據庫值”是當前存儲在數據庫中的值。

      此處可進行數據合并或用戶選擇等方式決策如何解決沖突。

      狀態斷開對象的處理

      EF Core判斷更新或添加數據是通過ChangeTrancker來進行的,這個操作需要在同一個DbContext中進行,而web應用通常先查詢到數據,然后將數據發送到客戶端進行相應的操作,隨后再由客戶端提交到服務器端,此時實體所在的DbContext已發生變化,如何判斷對實體進行更新或添加就成了一個問題。

      解決這個問題最簡單的方法是,更新和添加使用不同的web路徑,服務器端通過提供Add方法和Update方法來區分操作。

      除此之外,如果實體使用自動生成的主鍵,EF Core則可以通過判斷主鍵是否為默認值(null、0)來判斷是新增或更新。并且,對于這種情況,可直接使用DbContext的Update操作進行,在Update操作內部會完成該判斷。

      如果實體的主鍵不是自動生成的,則需要手工判斷實體是否存在。下面的代碼提供了一種添加或更新的思路:

      public static void InsertOrUpdate(BloggingContext context, Blog blog)
      {
          var existingBlog = context.Blogs.Find(blog.BlogId);
          if (existingBlog == null)
          {
              context.Add(blog);
          }
          else
          {
              context.Entry(existingBlog).CurrentValues.SetValues(blog);
          }
      
          context.SaveChanges();
      }
      

      SetValues方法將比較兩個實體的值,并對發生改變的屬性進行重新賦值,未發生改變的值保持不變,生成更新數據庫語句時也僅更新改變的字段。

      對于依賴關系的操作,同樣遵循以上幾種方式。

      刪除操作

      對于刪除操作,如果是刪除一個對象,則可以明確該對象的主鍵,并從數據庫中移除,此種情況不進行探討。

      這里需要探討的是,當對依賴關系中的列表進行部分刪除,如何進行更新的問題。例如Blog對象中有多個Post對象,如果從Blog中刪除部分Post,則意味著直接移除了Post對象,此時如果是斷開連接的情況,則EF Core無法跟蹤到Post實體列表的變更,從而導致無法正確的處理刪除。

      一種可用的方案是采用軟刪除,將數據標記為已刪除,此時的操作與更新相同。然后在查詢數據時,使用查詢篩選器,將標記為已刪除的數據過濾掉,從而達到刪除的效果。

      對于物理刪除,一種可用的方案是對Post列表進行對比,相應的代碼如下:

      public static void InsertUpdateOrDeleteGraph(BloggingContext context, Blog blog)
      {
          var existingBlog = context.Blogs
              .Include(b => b.Posts)
              .FirstOrDefault(b => b.BlogId == blog.BlogId);
      
          if (existingBlog == null)
          {
              context.Add(blog);
          }
          else
          {
              context.Entry(existingBlog).CurrentValues.SetValues(blog);
              foreach (var post in blog.Posts)
              {
                  var existingPost = existingBlog.Posts
                      .FirstOrDefault(p => p.PostId == post.PostId);
      
                  if (existingPost == null)
                  {
                      existingBlog.Posts.Add(post);
                  }
                  else
                  {
                      context.Entry(existingPost).CurrentValues.SetValues(post);
                  }
              }
      
              foreach (var post in existingBlog.Posts)
              {
                  if (!blog.Posts.Any(p => p.PostId == post.PostId))
                  {
                      context.Remove(post);
                  }
              }
          }
      
          context.SaveChanges();
      }
      
      posted @ 2019-07-14 16:46  拓荒者IT  閱讀(2337)  評論(0)    收藏  舉報
      皮膚配置 參考地址:https://www.yuque.com/awescnb/user
      主站蜘蛛池模板: 孟州市| 亚洲 成人 无码 在线观看| 东方四虎av在线观看| 亚洲第一成年免费网站| jlzz大jlzz大全免费| 手机在线看片不卡中文字幕| 4虎四虎永久在线精品免费| 日韩一区二区三区理伦片| 欧美成人精品手机在线| 国产成人精品无人区一区| 国产又爽又黄的激情视频| аⅴ天堂国产最新版在线中文| 国产精品一区二区久久精品| 亚洲天堂在线观看完整版| 加勒比中文字幕无码一区| 色成人亚洲| 做暖暖视频在线看片免费| 国产线播放免费人成视频播放| 亚洲国产区男人本色vr| 最新亚洲精品国偷自产在线| 欧美成人午夜精品免费福利| 涩涩爱狼人亚洲一区在线| 国产亚洲无线码一区二区| 国产午夜精品一区二区三区漫画| 成人aⅴ综合视频国产| 亚洲精品成人久久av| 欧美日韩高清在线观看| 国产午夜精品福利91| 国产九九视频一区二区三区| 亚州中文字幕一区二区| 四虎成人在线观看免费| 亚洲av色在线观看国产| 女人与牲口性恔配视频免费| 亚洲国产精品高清线久久| 日韩精品中文字幕人妻| 人妻系列无码专区久久五月天 | 国日韩精品一区二区三区| 国内精品久久久久精免费| 午夜亚洲国产理论片亚洲2020| 伊人久久大香线蕉AV网禁呦| 怀宁县|