Entity Framework 4.1 之二 : 覆蓋預設的約定
阿新 • • 發佈:2018-12-27
原文名稱:Entity Framework 4.1: Override conventions (2)
在這篇文章中,我將討論如何覆蓋預設的約定。
我們已經看過了在 EF4.1 Code First 中模型與資料庫中的預設約定。當這些約定不能滿足我們的時候,我們有兩種不同的途徑來覆蓋這些約定:
- 攔截模型的構建器,使用流暢的 API 來修改模型
- 為我們的模型增加標籤
publicclass Order
{
publicint OrderID { get; set; }
publicstring OrderTitle { get; set; }
publicstring CustomerName { get; set; }
public DateTime TransactionDate { get; set; }
}
構建器
我們從模型的構建器開始吧。為了使用模型構建器,我們必須重寫 DbContext 的一個方法 OnModelCreating.protectedoverridevoid OnModelCreating(DbModelBuilder modelBuilder)預設情況下,EF 將實體對映到資料庫中 dbo 架構下的同名表上,這裡我將訂單對映到資料庫中 efdemo 架構下的 Order 表。 模型構建器提供了一種流暢的 API 方式,由於方法返回同樣的物件,意味著可以使用鏈式的方法將操作連線在一起。下面是另外一個例子。
{
base.OnModelCreating(modelBuilder);
// Map schemas modelBuilder.Entity<Order>().ToTable("efdemo.Order");
}
modelBuilder.Entity在這裡,我們對屬性 OrderID 做了三件事:<Order>().Property(x => x.OrderID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.IsRequired()
.HasColumnName("TheOrderID");
- 標識它是標識列,自增長的列
- 必須的列,非空
- 對映到資料庫中的 TheOrderID
- 有智慧提示
- 有編譯時的錯誤檢查
- 屬性的型別是已知的,你可以在之後定義,例如,只有字串可以有最大或最小長度。
- 表必須屬於 dbo Schema
- OrderID 是主鍵,但不是自增長的型別
- 所有其他列是非空的
- 字串列的長度是 128
// Map schemas modelBuilder.Entity<Order>().ToTable("efdemo.Order");看起來有點冗長,但是不用修改模型,純粹的 POCO.
// 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,雖然使用的類並沒有來自 EF,而是 System.ComponentModel.DataAnnotations , .NET 的驗證模組。看一下例子吧。publicclass Order這裡我們告訴模型構建器將 OrderTitle 對映到非空的長度為32 的 nvarchar 列,最小長度為 2沒有對映到架構中,但是將被用來驗證。 這個例子我給出了一些業務標註,也可以加上一些技術標註。
{
publicint OrderID { get; set; }
[Required]
[StringLength(32, MinimumLength =2)]
publicstring OrderTitle { get; set; }
[Required]
[StringLength(64, MinimumLength =5)]
publicstring CustomerName { get; set; }
[Required]
public DateTime TransactionDate { get; set; }
}
publicclass Order這裡我們強制 OrderNumber 屬性作為主鍵,而且是一個自增長的列。 還可以使用 OnModelCreated 或者其他的標籤來覆蓋約定,有一些限制需要注意,例如(這是我注意到的):
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
publicint OrderNumber { get; set; }
…
}
- 表名不支援使用標籤進行標註
- 最小長度在 OnModelCreated 中不支援
- 正則表示式在 OnModelCreated 中不支援
- 使用標註來豐富模型的驗證規則
- 使用 OnModelCreated 來完成資料庫的約束(主鍵,自增長,表名,列型別等等)