asp.net core系列 34 EF保存數據(1)

来源:https://www.cnblogs.com/MrHSR/archive/2019/02/28/10448663.html
-Advertisement-
Play Games

一. 基本數據 每個EF上下文實例都有一個 ChangeTracker(更改跟蹤器),它負責跟蹤需要寫入資料庫的更改。 當更改實體類的實例時(修改屬性,刪除實例,新建實例等),這些更改會記錄在 ChangeTracker 中,然後在調用 SaveChanges 時被寫入資料庫。 此資料庫提供程式負責 ...


一. 基本數據

  每個EF上下文實例都有一個 ChangeTracker(更改跟蹤器),它負責跟蹤需要寫入資料庫的更改。 當更改實體類的實例時(修改屬性,刪除實例,新建實例等),這些更改會記錄在 ChangeTracker 中,然後在調用 SaveChanges 時被寫入資料庫。 此資料庫提供程式負責將更改,轉換為特定的資料庫操作(例如,關係資料庫的 INSERTUPDATE 和 DELETE 命令)。

 

  1.1 添加數據 

    使用 DbSet.Add 方法添加實體類的新實例。 調用 SaveChanges 時,數據將插入到資料庫中。

         var blog = new Blog { Url = "http://sample.com" };
         context.Blogs.Add(blog);
         context.SaveChanges();

 

  1.2 更新數據

    EF 將通過ChangeTracker自動檢測上下文對現有實體所做的更改。 檢測包括從資料庫查詢的實體,以及之前添加並保存到資料庫的實體。例如下麵示例,從資料庫查詢的實體,只需通過賦值來修改屬性,然後調用 SaveChanges 即可

         var blog = context.Blogs.First();
         blog.Url = "http://sample.com/blog";
         context.SaveChanges();

 

  1.3 刪除數據

    使用 DbSet.Remove 方法刪除實體類的實例。

    (1)如果實體已存在於資料庫中,則將在“SaveChanges”期間刪除該實體,並且刪除資料庫中的數據。

    (2)如果實體尚未保存到資料庫(即跟蹤為“已添加”),則在調用SaveChanges時,該實體會從上下文中移除且不再插入。

           //第一種情況
            var blog = context.Blogs.First();
            context.Blogs.Remove(blog);
            context.SaveChanges();
//第二種情況 Blog blog = new Blog() { Url = "www.baidu.com" }; //添加後該實體為已添加,尚未保存到資料庫 BloggingContext.Blogs.Add(blog); //刪除實體類的實例 BloggingContext.Blogs.Remove(blog); //從上下文中移除blog實體 BloggingContext.SaveChanges();

 

  1.4 單個 SaveChanges 中的多個操作

    可以將多個添加/更新/刪除操作合併到對“SaveChanges”的單個調用。

        // 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();

 

二.關聯數據

  除了上面對獨立實體進行保存外,還可以保存模型中定義的關係(主體實體和依賴實體)

    

  1.1 添加關係數據

    如果創建多個新的依賴實體,在添加主體到上下文時,也會添加其他依賴實體。在下麵的示例中,blog博客和三篇相關文章post將全部被插入資料庫中。 由於可通過 Blog.Posts 導航屬性訪問這些文章,因此可發現並添加它們(Posts三條信息到資料庫)。

    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();

  

  1.2 添加相關實體

    如果從上下文跟蹤的實體的導航屬性中,引用新實體。將發現該新實體並將其插入到資料庫中。在下麵的示例中,會保存 post 實體,因為該實體會添加到已從資料庫中提取的 blog 實體的 Posts 屬性。

      var blog = context.Blogs.Include(b => b.Posts).First();
      var post = new Post { Title = "Intro to EF Core" };
      //引用新實體, 
      blog.Posts.Add(post);
context.SaveChanges();

 

  1.3 更改關係

    如果更改實體的導航屬性,則將對資料庫中的外鍵列進行相應的更改。在下麵的示例中,post 依賴實體更新關係,關聯新的 blog主體實體,新 blog 會插入到資料庫中, post的導航屬性引用的新實體blog。

      //新增一個主體實體
      var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" };
      var post = context.Posts.First();
      //post更新關係
      post.Blog = blog;

      context.SaveChanges();

 

  1.4 刪除關係

    在下麵的示例中,對 Blog 和 Post 之間的關係配置了級聯刪除,因此將從資料庫中刪除 post 實體。         

      var blog = context.Blogs.Include(b => b.Posts).First();
      var post = blog.Posts.First();
       //刪除一條post依賴實體
      blog.Posts.Remove(post);

      context.SaveChanges();

 

三.聯級刪除 

  級聯刪除是指:允許在刪除某行時,自動觸發刪除相關的行。 即依賴實體與主實體的關係已斷開時,自動刪除該子實體,這通常稱為“刪除孤立項”。

  

  3.1 實體刪除示例

       var blog = context.Blogs.Include(b => b.Posts).First();
       var posts = blog.Posts.ToList();
       context.Remove(blog);

       context.SaveChanges();
  -- 解發SaveChanges後,刪除主體時,先自動刪除子實體(具有必選或可選關係的 DeleteBehavior.Cascade級聯)
    DELETE FROM [Posts] WHERE [PostId] = 1
    DELETE FROM [Posts] WHERE [PostId] = 2
    DELETE FROM [Blogs] WHERE [BlogId] = 1

    關於聯級刪除,涉及到的外鍵約束包括:可選關係(可以為 null 的外鍵) 和 必須關係(不可為 null 的外鍵),參考官網

 

. 事務       

   事務是指:允許以原子方式處理多個資料庫操作。 如果已提交事務,則所有操作都會成功應用到資料庫。 如果已回滾事務,則所有操作都不會應用到資料庫。關於數據事務的詳細介紹可網上查看。

 

  4.1 預設事務行為(隱式事務)

    預設情況下,如果資料庫提供程式支持事務,則會在事務中應用對 SaveChanges() 的單一調用中的所有更改。  這意味著SaveChanges() 可保證提交到資料庫完全成功或在出現錯誤時全部回滾。

    下麵來演示預設事務行為,建立blogs表的url欄位唯一約束。

    --創建唯一索引
    CREATE UNIQUE INDEX IX_Url ON Blogs(Url)
       //修改數據
       var blog = BloggingContext.Blogs.First();
        blog.Title = "123";

       //插入數據,再次插入違反約束
        BloggingContext.Blogs.Add(new Blog() { Url = "www.baidu.com" });
           
        BloggingContext.SaveChanges();

    檢查資料庫,該表數據沒有做任何更改,通過sql 監聽如下所示:

   

  4.2  控制事務(顯示事務)

    對於大多數應用程式,上面4.1 預設事務已足夠。 如果應用程式要求被視為有必要,則應該僅手動控制事務。

    可以使用 DbContext.Database API 開始、提交和回滾事務。 以下示例顯示了兩個 SaveChanges() 操作以及正在單個事務中執行的 LINQ 查詢。並非所有資料庫提供程式都支持事務。 調用事務 API 時,某些提供程式可能會引發異常或不執行任何操作

    using (var transaction = context.Database.BeginTransaction())
    {
        try
        {
            context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
            context.SaveChanges();

            context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
            context.SaveChanges();

            var blogs = context.Blogs
                .OrderBy(b => b.Url)
                .ToList();

            // Commit transaction if all commands succeed, transaction will auto-rollback when disposed if either commands fails
            transaction.Commit();
        }
        catch (Exception)
        {
            // TODO: Handle failure
        }
    }

  

  4.3 跨上下文事務(僅限關係資料庫)

    可以跨多個EF上下文實例,共用一個事務。 此功能僅在使用關係資料庫提供程式時才可用,因為該提供程式需要使用特定於關係資料庫的 DbTransaction 和 DbConnection

    (1) 允許在外部提供連接

      是指共用 DbConnection 時,需要在DbContext構造上下文時向其中傳入連接的功能。最簡單方式是停止使用預設的 DbContext.OnConfiguring 方法來配置上下文,在外部創建 DbContextOptions,然後將其傳遞到上下文構造函數。如下所示:

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);
    }
}

   (2)共用連接和跨上下文的事務

//創建共用連接
var options = new DbContextOptionsBuilder<BloggingContext>()
    .UseSqlServer(new SqlConnection(connectionString))
    .Options;

using (var context1 = new BloggingContext(options))
{
    using (var transaction = context1.Database.BeginTransaction())
    {
        try
        {
            context1.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
            context1.SaveChanges();

            using (var context2 = new BloggingContext(options))
            {
                context2.Database.UseTransaction(transaction.GetDbTransaction());

                var blogs = context2.Blogs
                    .OrderBy(b => b.Url)
                    .ToList();
            }

            // Commit transaction if all commands succeed, transaction will auto-rollback when disposed if either commands fails
            transaction.Commit();
        }
        catch (Exception)
        {
            // TODO: Handle failure
        }
    }
}

     未完...

 

 參考文獻:

    保存數據

 

 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 第二階段:提高階段 (中級PHP程式員)重點:提高針對LNMP的技能,能夠更全面的對LNMP有熟練的應用。目標:能夠隨時隨地搭建好LNMP環境,快速完成常規配置;能夠追查解決大部分遇到的開發和線上環境的問題;能夠獨立承擔中型系統的構架和開發工作;能夠在大型系統中承擔某個中型模塊的開發工作;1. Li ...
  • 事務的概念 一組要麼同時執行成功,要麼同時執行失敗的SQL語句,是資料庫操作的一個執行單元! 事務開始於: 連接到資料庫上,並執行一條DML語句(insert,update或delete),前一個事務結束後,又輸入了一條DML語句。 事務結束於: 1)執行commit或rollback語句。 2)執 ...
  • 在ASP.NET網站項目實際上線運行的過程中,有時候在運行環境下會出現400錯誤或者500錯誤,這些錯誤預設的頁面都不友好,比較簡單單調,其實我們可以自行設置這些錯誤所對應的頁面,讓這些錯誤跳轉到我們指定的路徑。此文將介紹如何在ASP.NET項目中設置404錯誤和500錯誤為例。 首先我們可以到網上 ...
  • 今天,我們將分享 Visual Studio 2019 的發佈候選版(RC 版) - 這是在 4 月 2 日的[虛擬發佈活動](https://launch.visualstudio.com/)上正式發佈之前的最後步驟之一。 您可以在 visualstudio.com/downloads 下載 RC... ...
  • 一、程式運行時產生的錯誤通過使用一種稱為異常(Exception)的機制在程式中傳遞,通過異常處理(Exception Handling)有助於處理程式運行過程中發生的意外或異常情況;異常可由CLR和客戶端代碼拋出(Throw),拋出的異常會在調用堆棧中傳遞,直到遇到可以捕獲該異常的語句進行處理並中 ...
  • 1 使用 WebShellKillerTool 進行網站文件掃描 能抓出一般後臺漏洞文件 2 控制面板-->文件夾選項-->顯示隱藏文件-->上面兩個如果是勾選狀態要去除 否則 有的文件會偽裝未受保護的系統文件 而不能被查看 3 檢查global 文件是否被篡改 4 檢查網站JS是否被註入特殊文件 ...
  • 1.前言 本篇文章通過ASP.NET Core的EPPlus包去操作Excel(導入導出),其使用原理與NPOI類似,導出Excel的時候不需要電腦上安裝office,非常好用 2.使用 新建一個ASP.NET Core Web應用程式(模型視圖控制器),還有一個類庫,SDK2.1版本,解決方案如下 ...
  • 在一些場合裡面,我們需要對一些記錄進行顏色標註處理,以標記記錄的信息重要性或者進行類別區分,如在客戶關係管理系統裡面,我們需要對客戶信息進行不同顏色的標註,方便對不同類別的管理,畢竟顏色區分還是比較直觀快速的一種。本隨筆介紹在我們的CRM客戶關係管理系統中,對客戶信息的標註處理和顯示區分的實現。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...