Entity Framework 4.1 之二 : 覆蓋默認的約定
原文名稱:Entity Framework 4.1: Override conventions (2)
看到 Entity Framework 4.1 推薦英文教程,為了幫大家看起來方便一些,簡單翻譯一下。這是一個系列,共有 8 篇,這是第 2 篇。
在這篇文章中,我將討論如何覆蓋默認的約定。
我們已經看過了在 EF4.1 Code First 中模型與數據庫中的默認約定。當這些約定不能滿足我們的時候,我們有兩種不同的途徑來覆蓋這些約定:
- 攔截模型的構建器,使用流暢的 API 來修改模型
- 為我們的模型增加標簽
在未來的版本中,我們還將有能力增加或者刪除約定,現在還沒有提供這個能力。
對于我們基本的例子,我們使用下面所示的訂單類。
public class Order
{
public int OrderID { get; set; }
public string OrderTitle { get; set; }
public string CustomerName { get; set; }
public DateTime TransactionDate { get; set; }
}
構建器
我們從模型的構建器開始吧。為了使用模型構建器,我們必須重寫 DbContext 的一個方法 OnModelCreating.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Map schemas
modelBuilder.Entity<Order>().ToTable("efdemo.Order");
}
默認情況下,EF 將實體映射到數據庫中 dbo 架構下的同名表上,這里我將訂單映射到數據庫中 efdemo 架構下的 Order 表。
模型構建器提供了一種流暢的 API 方式,由于方法返回同樣的對象,意味著可以使用鏈式的方法將操作連接在一起。下面是另外一個例子。
modelBuilder.Entity<Order>().Property(x => x.OrderID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.IsRequired()
.HasColumnName("TheOrderID");
在這里,我們對屬性 OrderID 做了三件事:
-
標識它是標識列,自增長的列
-
必須的列,非空
-
映射到數據庫中的 TheOrderID
這里,我們將涉及 EF4.1 的強大的功能:通過 Lambda 表達式,可以逐條定義屬性,而不是使用字符串來標識屬性,這有以下的優勢:
-
有智能提示
-
有編譯時的錯誤檢查
-
屬性的類型是已知的,你可以在之后定義,例如,只有字符串可以有最大或最小長度。
那么,通常我們重寫什么約定呢?看一下 Order 類,下面的情況不太符合默認約定:
-
表必須屬于 dbo Schema
-
OrderID 是主鍵,但不是自增長的類型
-
所有其他列是非空的
-
字符串列的長度是 128
我們可以通過模型構建器重寫這些約定:
// Map schemas
modelBuilder.Entity<Order>().ToTable("efdemo.Order");
// Identity Column
modelBuilder.Entity<Order>().Property(x => x.OrderID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// String columns
modelBuilder.Entity<Order>().Property(x => x.OrderTitle)
.IsRequired()
.HasMaxLength(64);
modelBuilder.Entity<Order>().Property(x => x.CustomerName)
.IsRequired()
.HasMaxLength(32);
// Date Columns
modelBuilder.Entity<Order>().Property(x => x.TransactionDate)
.IsRequired();
看起來有點冗長,但是不用修改模型,純粹的 POCO.
使用標注
現在,我們在看一下另外一種方式,使用標簽。
這種方式的代碼要少得多,感覺更加自然,通過標簽來說明屬性。唯一的問題是你的類不再 POCO,雖然使用的類并沒有來自 EF,而是 System.ComponentModel.DataAnnotations , .NET 的驗證模塊。看一下例子吧。
public class Order
{
public int OrderID { get; set; }
[Required]
[StringLength(32, MinimumLength = 2)]
public string OrderTitle { get; set; }
[Required]
[StringLength(64, MinimumLength = 5)]
public string CustomerName { get; set; }
[Required]
public DateTime TransactionDate { get; set; }
}
這里我們告訴模型構建器將 OrderTitle 映射到非空的長度為32 的 nvarchar 列,最小長度為 2沒有映射到架構中,但是將被用來驗證。
這個例子我給出了一些業務標注,也可以加上一些技術標注。
public class Order
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int OrderNumber { get; set; }
…
}
這里我們強制 OrderNumber 屬性作為主鍵,而且是一個自增長的列。
還可以使用 OnModelCreated 或者其他的標簽來覆蓋約定,有一些限制需要注意,例如(這是我注意到的):
-
表名不支持使用標簽進行標注
-
最小長度在 OnModelCreated 中不支持
-
正則表達式在 OnModelCreated 中不支持
著比較好理解,OnModelCreated 屬于表映射,(正則或者最小長度不能在數據庫中表示),標注支持常見的驗證。
我的原則:
-
使用標注來豐富模型的驗證規則
-
使用 OnModelCreated 來完成數據庫的約束(主鍵,自增長,表名,列類型等等)
這些方式可以使你的模型更加豐富而且保持 POCO,你可以到處重用你的模型,還能從驗證規則中獲得好處。
浙公網安備 33010602011771號