程式代碼優先慣例
Code First 可讓您使用 C# 或 Visual Basic .NET 類別來描述模型。 使用慣例偵測到模型的基本形狀。 慣例是一組規則,可用來在使用Code First時,根據類別定義自動設定概念模型。 慣例定義於 System.Data.Entity.ModelConfiguration.Conventions 命名空間中。
您可以使用資料批注或 Fluent API 進一步設定模型。 優先順序是透過 Fluent API 進行設定,後面接著數據批注,然後是慣例。 如需詳細資訊,請參閱使用 VB.NET 的數據批注、Fluent API - 關聯性、Fluent API - 類型和屬性和 Fluent API。
API 檔提供程式碼優先慣例的詳細清單。 本主題提供 Code First 所使用的慣例概觀。
類型探索
使用 Code First 開發時,您通常會從撰寫定義概念(領域)模型的 .NET Framework 類別開始。 除了定義類別之外,您還需要讓 DbContext 知道您要包含在模型中的類型。 若要這樣做,您可以定義衍生自 DbContext 的內容類別,並公開 您要成為模型一部分之類型的 DbSet 屬性。 程序代碼 First 會包含這些類型,也會提取任何參考型別,即使參考的類型是在不同的元件中定義也一樣。
如果您的類型參與繼承階層,就足以定義 基類的 DbSet 屬性,而且如果它們與基類位於相同的元件中,則衍生型別會自動包含。
在下列範例中,只有一個 DbSet 屬性定義於 SchoolEntities 類別 (Departments)。 Code First 會使用這個屬性來探索並提取任何參考的類型。
public class SchoolEntities : DbContext
{
public DbSet<Department> Departments { get; set; }
}
public class Department
{
// Primary key
public int DepartmentID { get; set; }
public string Name { get; set; }
// Navigation property
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
// Primary key
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
// Foreign key
public int DepartmentID { get; set; }
// Navigation properties
public virtual Department Department { get; set; }
}
public partial class OnlineCourse : Course
{
public string URL { get; set; }
}
public partial class OnsiteCourse : Course
{
public string Location { get; set; }
public string Days { get; set; }
public System.DateTime Time { get; set; }
}
如果您想要從模型排除類型,請使用 NotMapped 屬性或 DbModelBuilder.Ignore Fluent API。
modelBuilder.Ignore<Department>();
主鍵慣例
如果類別上的屬性名為 「ID」 (不區分大小寫),或類別名稱後面接著 「ID」,Code First 會推斷屬性是主鍵。 如果主鍵屬性的類型是數值或 GUID,則會設定為識別數據行。
public class Department
{
// Primary key
public int DepartmentID { get; set; }
. . .
}
關聯性慣例
在 Entity Framework 中,導覽屬性提供一種方式來巡覽兩個實體類型之間的關聯性。 每個物件都可以針對它所參與的每項關聯性擁有導覽屬性。 導覽屬性可讓您在雙向巡覽和管理關聯性,傳回參考物件(如果多重性是一或零或一個)或集合(如果多重性很多)。 Code First 會根據類型上定義的導覽屬性來推斷關聯性。
除了導覽屬性之外,建議您在代表相依物件的型別中包含外鍵屬性。 任何數據類型與主體主鍵屬性相同且名稱遵循下列其中一種格式的屬性代表關聯性的外鍵:『<navigation 屬性名稱><主體主鍵屬性名稱』、『<principal class name><primary key property name>』或 '<principal primary key property name>>'。 如果找到多個相符專案,則會依照上面所列的順序來指定優先順序。 外鍵偵測不區分大小寫。 偵測到外鍵屬性時,Code First 會根據外鍵的可為 Null 來推斷關聯性的乘數。 如果屬性可為 Null,則關聯性會註冊為選擇性;否則,關聯性會視需要註冊。
如果相依實體上的外鍵不可為 Null,則 Code First 會在關聯性上設定串聯刪除。 如果相依實體上的外鍵可為 Null,Code First 不會在關聯性上設定串聯刪除,而且當主體刪除時,外鍵會設定為 Null。 使用 Fluent API 可以覆寫慣例偵測到的多重性和串聯刪除行為。
在下列範例中,導覽屬性和外鍵是用來定義 Department 和 Course 類別之間的關聯性。
public class Department
{
// Primary key
public int DepartmentID { get; set; }
public string Name { get; set; }
// Navigation property
public virtual ICollection<Course> Courses { get; set; }
}
public class Course
{
// Primary key
public int CourseID { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
// Foreign key
public int DepartmentID { get; set; }
// Navigation properties
public virtual Department Department { get; set; }
}
注意
如果您在相同類型之間有多個關聯性(例如,假設您定義 Person 和 Book 類別,其中 Person 類別包含 ReviewedBooks 和 AuthoredBooks 導覽屬性,而 Book 類別包含 Author 和 Reviewer 導覽屬性),則必須使用數據批註或 Fluent API 手動設定關聯性。 如需詳細資訊,請參閱 數據批注 - 關聯 性和 Fluent API - 關聯性。
複雜類型慣例
當 Code First 探索無法推斷主鍵的類別定義,且沒有透過數據批注或 Fluent API 註冊主鍵時,類型會自動註冊為複雜類型。 複雜類型偵測也需要類型沒有參考實體類型的屬性,而且不會從另一種型別的集合屬性參考。 假設下列類別定義 Code First 會推斷 Details 是複雜類型,因為它沒有主鍵。
public partial class OnsiteCourse : Course
{
public OnsiteCourse()
{
Details = new Details();
}
public Details Details { get; set; }
}
public class Details
{
public System.DateTime Time { get; set; }
public string Location { get; set; }
public string Days { get; set; }
}
連線 ion 字串慣例
若要瞭解 DbContext 用來探索連線的慣例,請參閱 連線 和模型。
拿掉慣例
您可以移除 System.Data.Entity.ModelConfiguration.Conventions 命名空間中定義的任何慣例。 下列範例會 移除 PluralizingTableNameConvention。
public class SchoolEntities : DbContext
{
. . .
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure Code First to ignore PluralizingTableName convention
// If you keep this convention, the generated tables
// will have pluralized names.
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
自訂慣例
EF6 以後支援自定義慣例。 如需詳細資訊,請參閱 自定義程式代碼第一慣例。