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 Key
modelBuilder.Entity<OfficeAssignment>()
            .HasKey(t => t.InstructorID);

  也可以指定多個屬性為聯合主鍵

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

 

HasDatabaseGeneratedOption()

  為數字型主鍵取消數據庫生成

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

 

HasMaxLength() - Specifying the Length on a Property

  指定屬性長度

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

 

IsRequired() - Configuring the Property to be Required

  必填字段

// Configuring the Property to be Required
modelBuilder.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 Database
modelBuilder.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 Database
modelBuilder.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 Model
modelBuilder.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 Column
modelBuilder.Entity<Department>()
            .Property(p => p.Name)
            .HasColumnType("varchar");

 

Configuring Properties on a Complex Type

  在復雜類型(Complex Type)上有兩種方式來配置 scalar properties

  在 ComplexTypeConfiguration 上調用 Property

// Call Property on ComplexTypeConfiguration
modelBuilder.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 Token
modelBuilder.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 Token
modelBuilder.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 Type
modelBuilder.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 Database
modelBuilder.Ignore<OnlineCourse>();

 

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

  映射表名

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

  也可以同時指定 schema

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

 

Mapping the Table-Per-Hierarchy (TPH) Inheritance

  映射 TPH

// Mapping the Table-Per-Hierarchy (TPH) Inheritance
modelBuilder.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) Inheritance
modelBuilder.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) Inheritance
modelBuilder.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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM