Entity Framework 4.1 之二 : 覆蓋默認的約定


原文名稱:Entity Framework 4.1: Override conventions (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,你可以到處重用你的模型,還能從驗證規則中獲得好處。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com