上篇博文说过当我们定义的类不能遵循约定(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. 第8章 用户模式下的线程同步(4)_条件变量(Condition Variable)

    8.6 条件变量(Condition Variables)——可利用临界区或SRWLock锁来实现 8.6.1 条件变量的使用 (1)条件变量机制就是为了简化 “生产者-消费者”问题而设计的一种线程同 ...

  2. 搞netty

    开始搞netty了 查了下资料 在使用NIO 的时候,最好不要配置 SO_LINGER,假设设置了该參数,在 close的时候如缓冲区有数据待写出,会抛出 IOException. // 在netty ...

  3. Maven学习(九)插件介绍

    我们都知道Maven本质上是一个插件框架,它的核心并不执行任何具体的构建任务,所有这些任务都交给插件来完成,例如编译源代码是由maven-compiler-plugin完成的.进一步说,每个任务对应了 ...

  4. flexslider.js和waypoints.js一起用时的巨坑

    Flexslider has a callback API where you can execute functions after various actions:https://github.c ...

  5. bzoj2438[中山市选2011]杀人游戏

    Description 一位冷血的杀手潜入 Na-wiat,并假装成平民.警察希望能在 N 个人里面, 查出谁是杀手. 警察能够对每一个人进行查证,假如查证的对象是平民,他会告诉警察,他 认识的人, ...

  6. Jenkins 安装

    1. 调整tomcat的jvm配置, 以免内存不够, 在catalina.sh中 #!bin/sh下添加 JAVA_OPTS="-server -Xms1024m -Xmx1024m -XX ...

  7. C#事件快捷设置

    注解:本文摘自网络 C# 自定义带自定义参数的事件方法 C# 自定义带自定义参数的事件 需要经过以下几个步骤: 1.自定义事件参数 :要实现自定义参数的事件,首先要自定义事件参数.该参数是个类.继承自 ...

  8. mvc route的注册,激活,调用流程

    mvc route的注册,激活,调用流程(三) net core mvc route的注册,激活,调用流程 mvc的入口是route,当前请求的url匹配到合适的route之后,mvc根据route所 ...

  9. noi题库(noi.openjudge.cn) 1.8编程基础之多维数组T11——T20

    T11 图像旋转 描述 输入一个n行m列的黑白图像,将它顺时针旋转90度后输出. 输入 第一行包含两个整数n和m,表示图像包含像素点的行数和列数.1 <= n <= 100,1 <= ...

  10. 20145230GDB调试汇编堆栈过程分析

    20145230GDB调试汇编堆栈过程分析 分析过程 出现的问题:一开始无法编译,是因为我们的Linux中没有安装一个库. 进入之前先设置断点,之后disassemble可以获取汇编代码,用i r指令 ...