1. 程式人生 > >Entity Framework Code First (三)Data Annotations

Entity Framework Code First (三)Data Annotations

pos .cn ase image 希望 編程 create str length

Entity Framework Code First 利用一種被稱為約定(Conventions)優於配置(Configuration)的編程模式允許你使用自己的 domain classes 來表示 EF 所依賴的模型去執行查詢、更改追蹤、以及更新功能,這意味著你的 domain classes 必須遵循 EF 所使用的約定。然而,如果你的 domain classes 不能遵循 EF 所使用的約定,此時你就需要有能力去增加一些配置使得你的 classes 能夠滿足 EF 所需要的信息。

  Code First 提供了兩種方式來配置你的類:

  • DataAnnotations, 使用簡單屬性;
  • Fluent API, 以編程命令行式的方式來描述你的配置

  本文將關註 DataAnnotations(位於命名空間 System.ComponentModel.DataAnnotations

  為了便於示例,我們先創建兩個類:BlogPost

技術分享

  以上類都是遵循約定的,但是你也可以使用 annotations EF 提供更多的信息

Key主鍵

  EF 依賴於每一個實體都有一個主鍵從而能夠追蹤實體。 在約定下,主鍵是通過尋找名稱為 ID ClassName + ID 的屬性確定。那麽如果類中沒有此類的屬性呢?我們把類改造如下(把 Id 改為 PrimaryTrackingKey

技術分享

  此時如果我們添加 Scaffolded 會出現如下錯誤

技術分享

  我們需要使用 key annotation 確定哪一個屬性是主鍵

技術分享

  我們使用 Code First‘s Database Generation 功能看看數據庫的情況

技術分享

Required非空

  用於指示字段非空

技術分享

  運行看一下結果

技術分享

  我們在看一下後臺數據庫情況

技術分享

MaxLength and MinLength長度限制

  顧名思義,就是限制字段的長度

技術分享

  看一下後臺數據庫

技術分享

  運行看結果

技術分享

NotMapped忽略

  類中有些屬性,如通過計算獲得或其它列的合並而來的,我們並不希望其記錄在數據庫中,此時就可以使用 NotMapped Annotation

技術分享

  對於類也是一樣的

技術分享

ComplexType復雜類型

  一般這種情況是不常見的:類中包含另一個類即一個完整的實體是由一系列類的集合來描述。例如我們在我們的模型中增加一個叫 BlogDetails 的類

技術分享

  註意 BlogDetails 不包含任何主鍵屬性, 在領域驅動設計中被稱為值對象,而在 EF 中則被稱為復雜類型(ComplexType). Complex Types 是無法自我追蹤的,但是我們可以通過 ComplexType Annotation 來改變這種尷尬

技術分享

  可以看到,在數據庫中表 Blog 包含 BlogDetails 的所有兩個屬性,默認列名前綴為 complex typeBlogDetails

ConcurrencyCheck並發檢查

  ConcurrencyCheck Annotation 允許你可以在一個或多個屬性上設置一個標記用於當用戶更新或刪除實體時做並發檢查。

技術分享

  如果此時同時對此列進行更新,則會拋出異常 DbUpdateConcurrencyException

TimeStamp時間戳

  通常用行版本號或時間戳來檢查並發,除了使用 ConcurrencyCheck Annotation, 還可以使用更為精確的 TimsStamp, 前提是這個屬性的類型是字節數組(byte array). Code First 在對待 TimsStamp 屬性和 ConcurrencyCheck 屬性是一樣的,只不過能確保數據庫中生成的字段是 non-nullable

  在一個給定的類中只能有一個 TimsStamp 屬性

技術分享

  看一下後臺數據庫

技術分享

Table and Column表/列名

  指定匹配到數據庫的表/列名

技術分享

  可以看到表/列名已更改

DatabaseGenerated自增長

  技術分享

  DatabaseGeneratedOption 有三個選項:

  • DatabaseGeneratedOption.Computed 在用 Code First 生成數據庫的時候你可以在 byte timestamp 列上使用 DatabaseGenerated Annotation,否則就應該在數據庫存在的情況下使用因為如果數據庫不存在,此時 Code First 不知道為計算列(Computed Column)選擇使用什麽樣的公式
  • DatabaseGeneratedOption.Identity 如果主鍵為 integer 型,則數據庫默認為自增長(效果等同於設置DatabaseGeneratedOption.Identity), 如果主鍵是 GUID 類型,則要顯式設置自增長
  • DatabaseGeneratedOption.None 如果不想自增長,可設置成 DatabaseGeneratedOption.None

ForeignKey 外鍵

  技術分享

  看看數據庫

技術分享

InverseProperty屬性反轉

  InverseProperty 一般使用在當類間有多重關系的時候。

  例如在 Post 中你可能不僅需要追蹤誰寫的也還要追蹤有誰編輯了博客

技術分享

技術分享

  此時你會看到後臺數據庫有四個外鍵 Person_Id, Person_Id1, CreatedBy_Id and UpdatedBy_Id

技術分享

  為了解決這個問題,我們可以使用 InverseProperty annotation 來明確屬性間的指向

技術分享

  再一次看看數據庫,情況已經發生了變化

技術分享

Entity Framework Code First (三)Data Annotations