上篇博文说过当我们定义的类不能遵循约定(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; }
}

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();

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();

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

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

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

Entity Framework Code First (四)Fluent API - 配置属性/类型的更多相关文章

  1. Code First约定-Fluent API配置

    转自:http://blog.163.com/m13864039250_1/blog/static/2138652482015283397609/ 用Fluent API 配置/映射属性和类型 简介 ...

  2. Entity Framework Code First关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  3. Entity Framework Code First主外键关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  4. Entity Framework Code First关系映射约定【l转发】

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  5. 使用Fluent API 配置/映射属性和类型

    Code First约定-Fluent API配置 使用Fluent API 配置/映射属性和类型 简介 通常通过重写派生DbContext 上的OnModelCreating 方法来访问Code F ...

  6. Entity Framework Code First使用DbContext查询

    DbContext.DbSet及DbQuery是Entity Framework Code First引入的3个新的类,其中DbContext用于保持数据库会话连接,实体变化跟踪及保存,DbSet用于 ...

  7. Entity Framework 实体框架的形成之旅--Code First模式中使用 Fluent API 配置(6)

    在前面的随笔<Entity Framework 实体框架的形成之旅--Code First的框架设计(5)>里介绍了基于Code First模式的实体框架的经验,这种方式自动处理出来的模式 ...

  8. Entity Framework Code First (五)Fluent API - 配置关系

    上一篇文章我们讲解了如何用 Fluent API 来配置/映射属性和类型,本文将把重点放在其是如何配置关系的. 文中所使用代码如下 public class Student { public int ...

  9. Entity Framework Code First (五)Fluent API - 配置关系 转载 https://www.cnblogs.com/panchunting/p/entity-framework-code-first-fluent-api-configuring-relationships.html

    上一篇文章我们讲解了如何用 Fluent API 来配置/映射属性和类型,本文将把重点放在其是如何配置关系的. 文中所使用代码如下 public class Student { public int ...

随机推荐

  1. The Google Test and Development Environment (持续更新)

    最近Google Testing Blog上开始连载The Google Test and Development Environment(Google的测试和开发环境),因为blogspot被墙,我 ...

  2. ACCP 结业考试

    1) 在SQL Server 中,为数据库表建立索引能够(C ). 索引:是SQL SERVER编排数据的内部方法,是检索表中数据的直接通道 建立索引的作用:大大提高了数据库的检索速度,改善数据库性能 ...

  3. [技巧] 解决Win7下VMware中vmx86.sys报错的问题

    电梯直达 1楼 发表于 2012-7-2 15:14:22||倒序浏览|阅读模式 .pcb { margin-right: 0 } 当以普通用户权限运行的时候,VMware便会如此报错"无法 ...

  4. [No000040]取得一个文本文件的编码方式

    using System; using System.IO; using System.Text; /// <summary> /// 用于取得一个文本文件的编码方式(Encoding). ...

  5. gnuplot 的安装

    需要同时安装gnuplot和gnuplot-x11才能画出图 sudo apt-get install gnuplot gnuplot-x11 gnuplot not showing the grap ...

  6. NSIS来自己设定快捷方式的图标

    CreateShortCut 快捷文件.lnk 目标文件 参数 图标文件 图标索引号 启动选项 键盘快捷键 描述 CreateShortCut "$DESKTOP\快捷方式.lnk" ...

  7. header

    本文分享几个php header函数的例子,有需要的朋友参考学习下. 转自:http://www.jbxue.com/article/php_header_x5hV63c.html 1,可以使用hed ...

  8. 关于Xcode7.2版本访问相册问题

    前些天自己将xcode升级到7.2版本后,在我写的代码中有需要访问到相册的功能,但是却发现被告知无权限 一开始以为是手机问题,在设置里面找也没有找到,然后看代码,但是代码也没问题,后来才发现是我的pl ...

  9. 【转】【MySql】Waiting for table metadata lock原因分析

    MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...

  10. 【转】Sql Server参数化查询之where in和like实现详解

    转载至:http://www.cnblogs.com/lzrabbit/archive/2012/04/22/2465313.html 文章导读 拼SQL实现where in查询 使用CHARINDE ...