首页 > 代码库 > Entity Framework Code First (四)Fluent API - 配置属性/类型

Entity Framework Code First (四)Fluent API - 配置属性/类型

  上篇博文说过当我们定义的类不能遵循约定(Conventions)的时候,Code First 提供了两种方式来配置你的类:DataAnnotations 和 Fluent API, 本文将关注 Fluent API. 

  一般来说我们访问 Fluent API 是通过重写继承自 DbContext 的类中方法 OnModelCreating. 为了便于例示,我们先创建一个继承自 DbContext 的类,以及其它的一些类以便使用

技术分享
public class SchoolEntities : DbContext    {        public DbSet<Course> Courses { get; set; }        public DbSet<Department> Departments { get; set; }        public DbSet<Instructor> Instructors { get; set; }        public DbSet<OfficeAssignment> OfficeAssignments { get; set; }        protected override void OnModelCreating(DbModelBuilder modelBuilder)        {            // Configure Code First to ignore PluralizingTableName convention            // If you keep this convention then the generated tables will have pluralized names.            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();        }    }    public class Department    {        public Department()        {            this.Courses = new HashSet<Course>();        }        // Primary key        public int DepartmentID { get; set; }        public string Name { get; set; }        public decimal Budget { get; set; }        public System.DateTime StartDate { get; set; }        public int? Administrator { get; set; }        // Navigation property        public virtual ICollection<Course> Courses { get; private set; }    }    public class Course    {        public Course()        {            this.Instructors = new HashSet<Instructor>();        }        // 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 virtual ICollection<Instructor> Instructors { get; private set; }    }    public partial class OnlineCourse : Course    {        public string URL { get; set; }    }    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; }    }    public class Instructor    {        public Instructor()        {            this.Courses = new List<Course>();        }        // Primary key        public int InstructorID { get; set; }        public string LastName { get; set; }        public string FirstName { get; set; }        public System.DateTime HireDate { get; set; }        // Navigation properties        public virtual ICollection<Course> Courses { get; private set; }    }    public class OfficeAssignment    {        // Specifying InstructorID as a primary        [Key()]        public Int32 InstructorID { get; set; }        public string Location { get; set; }        // When the Entity Framework sees Timestamp attribute        // it configures ConcurrencyCheck and DatabaseGeneratedPattern=Computed.        [Timestamp]        public Byte[] Timestamp { get; set; }        // Navigation property        public virtual Instructor Instructor { get; set; }    }
View Code

 

Model-Wide Setting

 HasDefaultSchema() - Default Schema(EF6 onwards)

  从 EF6 开始可以使用 DbModelBuilder 中的方法 HasDefaultSchema 来指定所有的表/存储过程/视图等属于哪一个 database schema 

modelBuilder.HasDefaultSchema("sales");

  PS 1: EF 之前的版本中默认的 schema 是被 hard-coded 成 "dbo", 唯一改变它的方式是使用 ToTable API

  PS 2: 解释一下 database schema, 它就是对诸如表、视图、存储过程等的一种逻辑分组的方式(可以想象成对象的集合),你可以把一个 schema 赋予用户以便他能够访问所有经过授权的对象。Schemas 在数据库中可以被创建并被更新,用户也可以被授权访问它,一个 schema 可以被定义成任意用户拥有,并且 schema 的所有权是可以被转移的。我们可以看一下数据库中的 schema 

技术分享

 

 

Custom Conventions(EF6 onwards)

  约定配置请参考文章 http://www.cnblogs.com/panchunting/p/entity-framework-code-first-custom-conventions.html

 

Property Mapping 属性映射

HasKey() - Primary Key

  指定属性为主键 

// Primary KeymodelBuilder.Entity<OfficeAssignment>()            .HasKey(t => t.InstructorID);

  也可以指定多个属性为联合主键

// Composite Primary KeymodelBuilder.Entity<Department>()            .HasKey(t => new { t.DepartmentID, t.Name });

 

HasDatabaseGeneratedOption()

  为数字型主键取消数据库生成

// Switching off Identity for Numeric Primary KeysmodelBuilder.Entity<Department>()            .Property(t => t.DepartmentID)            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

 

HasMaxLength() - Specifying the Length on a Property

  指定属性长度

// Specifying the Maximum Length on a PropertymodelBuilder.Entity<Department>()            .Property(t => t.Name)            .HasMaxLength(50);

 

IsRequired() - Configuring the Property to be Required

  必填字段

// Configuring the Property to be RequiredmodelBuilder.Entity<Department>()            .Property(t => t.Name)            .IsRequired();

 

Ignore() - Specifying Not to Map a CLR Property to a Column in the Database

  忽略

// Specifying Not to Map a CLR Property to a Column in the DatabasemodelBuilder.Entity<Department>()            .Ignore(t => t.Budget);

 

HasColumnName() - Mapping a CLR Property to a Specific Column in the Database

  指定列名

// Mapping a CLR Property to a Specific Column in the DatabasemodelBuilder.Entity<Department>()            .Property(t => t.Name)            .HasColumnName("DepartmentName");

 

 MapKey - Renaming a Foreign Key That Is Not Defined in the Model

  指定外键名

// Renaming a Foreign Key That Is Not Defined in the ModelmodelBuilder.Entity<Course>()            .HasRequired(c => c.Department)            .WithMany(t => t.Courses)            .Map(m => m.MapKey("ChangedDepartmentID"));

 

HasColumnType() - Configuring the Data Type of a Database Column

  指定列类型

// Configuring the Data Type of a Database ColumnmodelBuilder.Entity<Department>()            .Property(p => p.Name)            .HasColumnType("varchar");

 

Configuring Properties on a Complex Type

  在复杂类型(Complex Type)上有两种方式来配置 scalar properties

  在 ComplexTypeConfiguration 上调用 Property

// Call Property on ComplexTypeConfigurationmodelBuilder.ComplexType<Details>()            .Property(t => t.Location)            .HasMaxLength(20);

  也可以使用点标记法来访问复杂类型上的属性

 // Use the dot notation to access a property of a complex type modelBuilder.Entity<OnsiteCourse>()             .Property(t => t.Details.Location)             .HasMaxLength(20);

 

IsConcurrencyToken() - Configuring a Property to Be Used as an Optimistic Concurrency Token

  设置乐观并发标记

// Configuring a Property to Be Used as an Optimistic Concurrency TokenmodelBuilder.Entity<OfficeAssignment>()            .Property(t => t.Timestamp)            .IsConcurrencyToken();

 

IsRowVersion() - Configuring a Property to Be Used as an Optimistic Concurrency Token

  设置乐观并发标记,效果同上

// Configuring a Property to Be Used as an Optimistic Concurrency TokenmodelBuilder.Entity<OfficeAssignment>()            .Property(t => t.Timestamp)            .IsRowVersion();

 

 

Type Mapping类型映射

ComplexType() - Specifying That a Class Is a Complex Type

  指定复杂类型

// Specifying That a Class Is a Complex TypemodelBuilder.ComplexType<Details>();

 

Ingore() - Specifying Not to Map a CLR Entity Type to a Table in the Database

  忽略实体类型

// Specifying Not to Map a CLR Entity Type to a Table in the DatabasemodelBuilder.Ignore<OnlineCourse>();

 

ToTable() - Mapping an Entity Type to a Specific Table in the Database

  映射表名

// Mapping an Entity Type to a Specific Table in the DatabasemodelBuilder.Entity<Department>()            .ToTable("t_Department");

  也可以同时指定 schema

// Mapping an Entity Type to a Specific Table in the DatabasemodelBuilder.Entity<Department>()            .ToTable("t_ Department", "school");

 

Mapping the Table-Per-Hierarchy (TPH) Inheritance

  映射 TPH

// Mapping the Table-Per-Hierarchy (TPH) InheritancemodelBuilder.Entity<Course>()            .Map<Course>(m => m.Requires("Type").HasValue("Course"))            .Map<OnsiteCourse>(m => m.Requires("Type").HasValue("OnsiteCourse"));

 

Mapping the Table-Per-Type (TPT) Inheritance

  映射 TPT

// Mapping the Table-Per-Type (TPT) InheritancemodelBuilder.Entity<Course>().ToTable("Course");modelBuilder.Entity<OnsiteCourse>().ToTable("OnsiteCourse");

 

Mapping the Table-Per-Concrete Class (TPC) Inheritance

  映射 TPC

// Mapping the Table-Per-Concrete Class (TPC) InheritancemodelBuilder.Entity<Course>()            .Property(c => c.CourseID)            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);modelBuilder.Entity<OnsiteCourse>()            .Map(m =>            {                m.MapInheritedProperties();                m.ToTable("OnsiteCourse");            });modelBuilder.Entity<OnlineCourse>()            .Map(m =>            {                m.MapInheritedProperties();                m.ToTable("OnlineCourse");            });

 

Mapping Properties of an Entity Type to Multiple Tables in the Database (Entity Splitting)

  映射实体中属性到多张表中

  • 实体 Department 属性 DepartmentID, Name 映射到表 Department;
  • 同时属性  DepartmentID, Administrator, StartDate, Budget  映射到表 DepartmentDetails 
// Mapping Properties of an Entity Type to Multiple Tables in the Database (Entity Splitting)modelBuilder.Entity<Department>()            .Map(m =>            {                m.Properties(t => new { t.DepartmentID, t.Name });                m.ToTable("Department");            })            .Map(m =>            {                m.Properties(t => new { t.DepartmentID, t.Administrator, t.StartDate, t.Budget });                m.ToTable("DepartmentDetails");            });

 

Mapping Multiple Entity Types to One Table in the Database (Table Splitting)

  映射多个实体到一张表:实体 Instructor 和 OfficeAssignment 映射到同一张表 Instructor

// Mapping Multiple Entity Types to One Table in the Database (Table Splitting)modelBuilder.Entity<OfficeAssignment>()            .HasKey(t => t.InstructorID);modelBuilder.Entity<Instructor>()            .HasRequired(t => t.OfficeAssignment)            .WithRequiredPrincipal(t => t.Instructor);modelBuilder.Entity<Instructor>().ToTable("Instructor");modelBuilder.Entity<OfficeAssignment>().ToTable("Instructor");

 

Mapping an Entity Type to Insert/Update/Delete Stored Procedures (EF6 onwards)

  映射实体到增、改、更、删 存储过程,详情请参考文章 http://www.cnblogs.com/panchunting/p/entity-framework-code-first-insert-update-delete-stored-procedures

PS: 关于TPH, TPT, TPC 以后有时间专门写一篇文章介绍 

原文参考:http://msdn.microsoft.com/en-us/data/jj591617

 摘抄:http://www.cnblogs.com/panchunting/p/entity-framework-code-first-fluent-api-configuring-mapping-properties-and-types.html

Entity Framework Code First (四)Fluent API - 配置属性/类型