上篇博文说过当我们定义的类不能遵循约定(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. 06章 Struts2数据校验

    一.三种实现方式 ① 用validate()方法实现数据校验 继承ActionSupport类,该类实现了Validateable接口,该接口中定义了一个validate()方法,在自定义的Actio ...

  2. sql索引的填充因子多少最好,填充因子的作用?

    当创建一个新索引,或重建一个存在的索引时,你可以指定一个填充因子,它是在索引创建时索引里的数据页被填充的数量.填充因子设置为100意味着每个索引页100%填满,50%意味着每个索引页50%填满. 如果 ...

  3. Android驱动入门-LED--HAL硬件访问服务层②

    硬件平台: FriendlyARM Tiny4412 Cortex-A9 操作系统: UBUNTU 14.04 LTS 时间:2016-09-21  16:58:56 为了避免访问冲突,则创建了硬件访 ...

  4. 移植SDL运行库到Tiny6410 上

    在移植游戏之前, 我们首先需要将 SDL/SDL_mixer/SDL_ttf/SDL_image 这四个库移植到 Tiny6410 上, 另外还需要 iconv 库. libiconv-1.13.1. ...

  5. [No000026]365种创业、办公、和生活成长的精华资源

    只需要具备以下技能,人人都可以成为企业家:经得起失败的考验,思维活跃,新点子不断,能够脚踏实地把新点子转化为产品,并在这个过程中坚持不懈,百折不挠,即使跌倒了,也要及时从失败中学习,迅速投入到下一次冒 ...

  6. window10 安装出现the error code is 2503错误的解决方法

    window10 安装出现the error code is 2503错误的解决方法:  设置 C:\WINDOWS\TEMP的权限

  7. SQL SERVER的连接方式

    最近在做项目的时候,遇到了SQLSERVER的连接,以前是很模糊的,现在做一个简单的总结. 针对SQL_SERVER,连接指定的方式有两种,一种是Where条件指定方式,另外一种是采用On连指定连接条 ...

  8. 去掉Win7资源管理器左侧导航窗格中的收藏夹、库等的方法

    去掉Win7资源管理器的收藏夹/库/家庭组/网络的方法 将Windows 7资源管理器左侧导航窗格中的收藏夹.库.家庭组.网络全部去掉,只剩下计算机, 以收藏夹为例作简要说明. 首先打开注册表编辑器, ...

  9. Java集合系列:-----------05LinkedList的底层实现

    前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类--LinkedList.和学习ArrayList一样,接下来呢,我们先对LinkedList ...

  10. 让Bootstrap轮播插件carousel支持左右滑动手势的三种方法

    因为最近开发的项目涉及到移动设备上的 HTML5 开发,其中需要实现轮播效果.然后最快捷的方式,你知道的(Bootstrap),然后原生的 Bootstrap 的 carousel.js 插件并没有支 ...