asp.net core系列 24 EF模型配置(主鍵,生成值,最大長度,併發標記)

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

一.主鍵 鍵用作每個實體實例的主要唯一標識符。 使用關係資料庫時,這會映射到主鍵的概念。 還可以配置不是主鍵的唯一標識符。按照約定,名為 Id 或 <type name>Id 的屬性會配置為實體的鍵。例如下麵二個示例: 除了上面講到的約定,還可以用數據註釋將單個屬性配置為實體的鍵,下麵示例使用數據註 ...


一.主鍵

  鍵用作每個實體實例的主要唯一標識符。 使用關係資料庫時,這會映射到主鍵的概念。 還可以配置不是主鍵的唯一標識符。按照約定,名為 Id 或 <type name>Id 的屬性會配置為實體的鍵。例如下麵二個示例:

class Car
{
    //映射到Car表 Id主鍵
    public string Id { get; set; }
}
class Car
{
    //映射到Car表CarId主鍵,約定格式:<type name>Id
    public string CarId { get; set; }
}

  除了上面講到的約定,還可以用數據註釋將單個屬性配置為實體的鍵,下麵示例使用數據註釋配置主鍵

class Car
{
   //映射到Car表LicensePlate主鍵
    [Key]
    public string LicensePlate { get; set; }
}

  還可以使用 Fluent API 將單個屬性配置為實體的鍵。下麵示例使用Fluent API配置主鍵

    class MyContext : DbContext
  {
      public DbSet<Car> Cars { get; set; }

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          modelBuilder.Entity<Car>().HasKey(c => c.LicensePlate);
      }
  }

    class Car
    {
        public string LicensePlate { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
    }

  還可以使用 Fluent API 將多個屬性配置為實體的鍵(稱為複合鍵)。 只能使用 Fluent API 配置複合鍵 - 不能使用約定來設置複合鍵,也不能使用數據註釋來配置複合鍵

class MyContext : DbContext
{
    public DbSet<Car> Cars { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Car>()
            .HasKey(c => new { c.State, c.LicensePlate });
    }
}

 

二.生成的值

  對於屬性的值生成模式有三種:(1) 無值生成;(2) 在新增時自動生成值;(3) 在添加或更新時自動生成值。下麵介紹數據註釋中使用DatabaseGeneratedOption枚舉來實現,說明這三種生成模式的應用場景:

 public class Blog
{
    //沒有值生成, 主鍵一般在資料庫中都是自增,所以在EF中不需要給值
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int BlogId { get; set; }

    //在新增時生成值, 一般插入一條數據時,記錄插入的時間
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime Inserted { get; set; }
    
    //在新增或修改時生成值, 一般記錄修改的時間。
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime LastUpdated { get; set; }
}

  除了用數據註釋方法生成值,還可以使用Fluent API用於更改某一給定屬性的值生成模式。

    //沒有值生成
    modelBuilder.Entity<Blog>().Property(b => b.BlogId).ValueGeneratedNever();
    //在新增時生成值
    modelBuilder.Entity<Blog>().Property(b => b.Inserted).ValueGeneratedOnAdd();
    //在新增或修改時生成值
    modelBuilder.Entity<Blog>().Property(b => b.LastUpdated).ValueGeneratedOnAddOrUpdate();

 

三. 最大長度

  最大長度僅適用於數組,數據類型,如 string 和 byte[]。將數據傳遞到提供程式之前,實體框架不會執行任何最大長度驗證。 由提供程式或數據存儲在適當時機進行驗證。以 SQL Server 為目標,超過最大長度將引發異常。

  使用數據註釋來配置屬性的最大長度。 此示例面向 SQL Server,因此使用數據類型 nvarchar(500)。

public class Blog
{
    public int BlogId { get; set; }
    [MaxLength(500)]
    public string Url { get; set; }
}

  使用 Fluent API 配置屬性的最大長度。 此示例面向 SQL Server,因此使用數據類型 nvarchar(500)

    modelBuilder.Entity<Blog>().Property(b => b.Url).HasMaxLength(500);

 

四.併發標記

  配置併發標記是用於解決資料庫中的併發衝突。資料庫併發:指多個進程或用戶同時訪問或更改資料庫中的相同數據的情況。 併發控制:指的是用於在發生併發更改時確保數據一致性的特定機制。

  併發標記的實現是通過EF Core來實現併發衝突的解決,而非在資料庫層面的方案。EF Core 實現了樂觀併發控制(非資料庫層面),這意味著它將允許多個進程或用戶獨立進行更改,而不會產生同步或鎖定的開銷。 在理想情況下,這些更改將不會相互干擾,因此都能夠成功。 在最壞的情況下,兩個或更多進程將嘗試進行衝突更改,而其中只有一個進程會成功。

 

  4.1 併發控制在 EF Core 中的工作原理:

    配置為併發標記的屬性用於實現樂觀併發控制:每當在 SaveChanges 期間執行更新或刪除操作時,會將資料庫上的併發標記屬性值與通過 EF Core 讀取的原始值進行比較:

    (1) 如果這些值匹配,則可以完成該操作。

    (2) 如果這些值不匹配,EF Core 會假設另一個用戶已執行衝突操作,並中止當前事務。這種情況被稱為"併發衝突"。

    當配置好併發標記後,資料庫提供程式負責實現併發標記值的比較,EF Core 會對任何 UPDATE 或 DELETE 語句的 WHERE 子句中的併發標記值進行檢查。執行這些語句後,EF Core 會讀取受影響的行數。如果未影響任何行,將檢測到併發衝突,並且 EF Core 會引發 DbUpdateConcurrencyException

    例如,將 Person 的 LastName 配置為併發標記。 這樣,對 Person 的任何更新操作(併發標記的屬性必須作為比較參照來反映併發衝突),都將在 WHERE 子句中做併發檢查,在資料庫端將執行如下sql命令,條件LastName 是EF自動加上去:

  UPDATE [Person] SET [FirstName] = @p1 WHERE [PersonId] = @p0 AND [LastName] = @p2;

    

    併發標記後會有三組值可用於幫助解決併發衝突:

      1.“當前值”是應用程式嘗試寫入資料庫的值。
      2.“原始值”是在進行任何編輯之前最初從資料庫中檢索的值。
      3.“資料庫值”是當前存儲在資料庫中的值。

 

    產生併發衝突的常規處理步驟是:
      1.在 SaveChanges 期間捕獲 DbUpdateConcurrencyException。
      2.使用 DbUpdateConcurrencyException.Entries 為受影響的實體準備一組新更改。
      3.刷新併發標記的原始值以反映資料庫中的當前值。
      4.重試該過程,直到不發生任何衝突。

 

  下麵使用數據註釋方法將LastName屬性配置為併發標記

public class Person
{
    public int PersonId { get; set; }

    [ConcurrencyCheck]
    public string LastName { get; set; }

    public string FirstName { get; set; }
}

  下麵使用Fluent API 可用於將LastName屬性配置為併發標記

   modelBuilder.Entity<Person>().Property(p => p.LastName).IsConcurrencyToken();

  

  總結:併發衝突的產生,一般只有在生產環境或模擬大量用戶線程的情況下才可能產生關係型資料庫的併發死鎖。產生死鎖的原因有很多,如未建索引導致表掃描、或未按同一順序訪問對象等。只有分析出死鎖的原因( sqlserver 死鎖分析) (mysql死鎖分析),才考慮結合EF的併發標記來解決。

 

  參考文獻:

    官方資料: 主鍵

            生成的值

            最大長度

            併發標記

    


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

-Advertisement-
Play Games
更多相關文章
  • 1.Laravel訪問出錯錯誤信息:`Warning: require(/vendor/autoload.php):failed to open stream: No such file or dire 錯誤信息:`Warning: require(/http/www.mywakavLee.cn/b ...
  • 據說表格的方式一目瞭然 一. java數據類型的取值範圍如下: 註意:long型後如果不加 L 則預設為int型,float型如果不加 F 則預設為double型; 註意!註意!註意! 二. 基本數據類型根據取值範圍由低到高排序為: 三. java中可以直接輸出該最大值: 結果: ...
  • docker出來也有很多年了,但用到的公司其實並不是很多,docker對傳統開發是一個革命性的,幾乎顛覆了之前我們傳統的開發方法和部署模式,而大多 公司保守起見或不到萬不得已基本上不會去變更現有模式。 一:Docker出現之前我們都有哪些困惑 1. 應用依賴多,系統參數配置雜,部署起來麻煩 這句話怎 ...
  • 什麼是SpringCloud? SpringCloud是一個分散式的整體解決方案。SpringCloud為開發者提供了在分散式系統中快速構建的工具,使用SpringCloud可以快速的啟動服務或構建應用、同時能夠快速和雲平臺資源進行對接。 SpringCloud分散式開發五大常用組件 服務發現——N ...
  • 前段時間有寫過一個計算多邊形角度的代碼,這裡給它整理整理,留給自己也送給萌新。 看左下圖,這是一個多環的多邊形,一個外環(內部為多邊形內部區域),一個內環(外部為多邊形內部區域),同時多邊形中任意一個角不等於零角(等於 0° 的角)或周角(等於 360° 的角)。註意:本文下文所討論的多邊形求角度不 ...
  • 電子畫板開發需求 教師端需求: 教師登錄後能創建房間(教室) 學生加入房間後有通知提醒 教師能夠解散房間 基本的畫板功能 學生端需求: 能夠切換不同線上的房間 能夠收到新建房間的通知 能夠收到房間解散的通知 基本的畫板同步功能 本文原文地址:https://www.limitcode.com/det ...
  • 嗨咯,小編在此祝大家新年快樂財多多! 今天我們來盤一盤人臉註冊、人臉識別等相關操作,這是一個簡單入門教程。 話不多說,我們進入主題: 完成人臉識別所需的步驟: 1、註冊百度賬號api,創建自己的應用 註冊地址: https://login.bce.baidu.com/ 註冊登錄之後,在“產品服務” ...
  • 對比 準備數據 實體類: 定義: 使用DataContractJsonSerializer 幫助類: 用法: 輸出: 使用JavaScriptSerializer 使用Silverlight 使用JSON.NET 輸出: ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...