定义一个继承自EntityTypeConfiguration<>泛型类的类来定义domain中每个类的数据库配置,在这个自定义类的构造函数中使用我们上次提到的那些方法配置数据库的映射。

映射实例

this.HasRequired(s => s.Company).WithMany().HasForeignKey(s => s.CompanyId);
this.HasOptional(s => s.User).WithMany().HasForeignKey(s => s.UserId);
this.HasRequired(s => s.User).WithOptional(s => s.WXUser);
this.Property(s => s.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);
this.HasRequired(p => p.User).WithOptional(p => p.UserDepartment);
this.HasMany(s => s.Tags);
this.HasMany(s => s.CompanyAdminUsers).WithRequired().HasForeignKey(s => s.CompanyId);
HasMany(s => s.Images).WithOptional().HasForeignKey(s => s.FeedbackId);
modelBuilder.Entity<Course>()
.HasRequired(c => c.Department)
.WithMany(t => t.Courses)
.Map(m => m.MapKey("ChangedDepartmentID"));

待读:http://www.aizhengli.com/entity-framework6-code-first-get-started/95/entity-framework-code-first--fluent-api.html

实体类关系的映射

实体类映射中,关系的映射配置在关系的两端都可以配置。例如,用户信息与登录信息的 一对多 关系可以在用户信息端配置:

HasMany(m => m.LoginLogs).WithRequired(n => n.Member);

等效于在登录日志信息端配置:

HasRequired(m => m.Member).WithMany(n => n.LoginLogs);

但是,如果所有的关系映射都在作为主体的用户信息端进行配置,势必造成用户信息端配置的臃肿与职责不明。所以,为了保持各个实体类型的职责单一,实体关系推荐在关系的非主体端进行映射。

用户信息映射类,用户信息是关系的主体,所有的关系都不在此映射类中进行配置

namespace GMF.Demo.Core.Data.Configurations
{
public class MemberConfiguration : EntityTypeConfiguration<Member>
{
}
}

用户扩展信息映射类,配置用户扩展信息与用户信息的 0:1 关系

namespace GMF.Demo.Core.Data.Configurations
{
public class MemberExtendConfiguration : EntityTypeConfiguration<MemberExtend>
{
public MemberExtendConfiguration()
{
HasRequired(m => m.Member).WithOptional(n => n.Extend);
}
}
}

OnModelCreating配置

  1. ToTable - TableAttribute:配置此实体类型映射到的表名
  2. HasColumnName - ColumnAttribute:配置用于存储属性的数据库列的名称
  3. HasForeignKey - ForeignKeyAttribute:将关系配置为使用在对象模型中的外键属性。如果未在对象模型中公开外键属性,则使用Map方法
  4. Ignore - NotMappedAttribute:从模型中排队某个属性,使该属性不会映射到数据库
  5. HasRequired:通过此实体类型配置必需关系。除非指定此关系,否则实体类型的实例将无法保存到数据库。数据库中的外键不可为null。
  6. HasOptional:从此实体类型配置可选关系。实体类型的实例将能保存到数据库,而无需指定此关系。数据库中的外键可为null。
  7. HasMany:从此实体类型配置一对多关系。
  8. WithOptional:将关系配置为required:optional。(required:0…1端的1,表示必需,不可为null;optional:0…1端的0,表示可选,可为null。下同)
  9. WithOptionalDependent:将关系配置为optional:optional。要配置的实体类型将成为依赖对象,且包含主体的外键。作为关系目标的实体类型将成为关系中的主体。
  10. WithOptionalPrincipal:将关系配置为optional:optional。要配置的实体类型将成为关系中的主体。作为关系目标的实体类型将成为依赖对象,且包含主体的外键。
  11. WithRequired:将关系的指定端配置为必需的,且在关系的另一端有导航属性。
  12. WithRequiredDependent:将关系配置为required:required。要配置的实体类型将成为依赖对象,且包含主体的外键。作为关系目标的实体类型将成为关系中的主体。
  13. WithRequiredPrincipal:将关系配置为required:required。要配置的实体类型将成为关系中的实体。作为关系目标的实体类型将成为依赖对象,且包含主体的外键。
  14. WillCascadeOnDelete:配置是否对关系启用级联删除。
  15. Map:将关系配置为使用未在对象模型中公开的外键属性。可通过指定配置操作来自定义列和表。如果指定了空的配置操作,则约定将生成列名。如果在对象模型中公开了外键属性,则使用 HasForeignKey 方法。并非所有关系都支持在对象模型中公开外键属性。
  16. MapKey:配置外键的列名。
  17. ToTable:配置外键列所在表的名称和架构。

属性映射

主要配置:主键、数值长度、配置为必须、不映射,外键等

配置主键:

modelBuilder.Entity<ClassA>().HasKey(t => t.ID);    //配置ClassA的ID属性为主键

配置联合主键:

modelBuilder.Entity<ClassA>().HasKey(t => new { t.ID, t.Name });    //配置ClassA的ID和Name为主键

设置数据非数据库生成:

modelBuilder.Entity<ClassA>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);    //ClassA的Id属性不用数据库控制生成

设置字段最大长度:

modelBuilder.Entity<ClassA>().Property(t => t.Name).HasMaxLength(100);     //设置ClassA类的Name属性的最大长度为100,如果值长度100,会抛出 DbEntityValidationException异常

设置字段为必需:

modelBuilder.Entity<ClassA>().Property(t =>t.Id).IsRequired();   //设置ClassA类的Id属性为必需   

属性不映射到数据库:

modelBuilder.Entity<ClassA>().Ignore(t => t.A);    //调过ClassA类的A属性,让之不映射到数据库中

将属性映射到数据库中特定列名:

modelBuilder.Entity<ClassA>()
.Property(t => t.A)
.HasColumnName("A_a"); //将类ClassA的属性A映射到数据库中对应列名A_a

类中不指定外键,但在数据库中指定外键名:

modelBuilder.Entity<Staff>()
.HasRequired(c => c.Department)
.WithMany(t => t.Staffs)
.Map(m => m.MapKey("DepartmentID")); //指定员工表中DepartmentID为Staff到Department的外键

指定属性映射的字段为Unicode类型:

modelBuilder.Entity<ClassA>()
.Property(t => t.Name)
.IsUnicode(true);

设置属性映射的列的类型:

modelBuilder.Entity<Department>()
.Property(p => p.Name)
.HasColumnType("varchar"); //设置列为varchar类型

设置复杂类型的属性(何为复杂类型? 没指定主键的类型):

modelBuilder.ComplexType<Details>()
.Property(t => t.Location)
.HasMaxLength(20);
modelBuilder.Entity<OnsiteCourse>()
.Property(t => t.Details.Location)
.HasMaxLength(20);

显示设定为复杂类型:

modelBuilder.ComplexType<ClassA>();

将属性配置为用作乐观并发令牌:

方法1、用 ConcurrencyCheck 特性或 IsConcurrencyToken 方法

modelBuilder.Entity<OfficeAssignment>()
.Property(t => t.Timestamp)
.IsConcurrencyToken();

方法2、IsRowVersion 

modelBuilder.Entity<OfficeAssignment>()
.Property(t => t.Timestamp)
.IsRowVersion();

忽略类型,不映射到数据库中:

modelBuilder.Ignore<OnlineCourse>();

设置索引

您必须添加引用 ︰using System.Data.Entity.Infrastructure.Annotations;

基本例子

在这里是一种简单的用法,加上 User.FirstName属性的索引

modelBuilder
.Entity<User>()
.Property(t => t.FirstName)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute()));

实例 ︰

在这里是一个更现实的例子。它对多个属性添加一个 唯一索引 ︰ User.FirstName和 User.LastName,与索引名称"IX_FIrstNameLastName"

modelBuilder
.Entity<User>()
.Property(t => t.FirstName)
.IsRequired()
.HasMaxLength()
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_FirstNameLastName", ) { IsUnique = true })); modelBuilder
.Entity<User>()
.Property(t => t.LastName)
.IsRequired()
.HasMaxLength()
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(
new IndexAttribute("IX_FirstNameLastName", ) { IsUnique = true }));

数据库模型发生改变的处理

暴力处理:直接删除掉后重新生成

namespace Portal
{
public class PortalContext : DbContext
{
static PortalContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<PortalContext>());
} public DbSet<Province> Provinces { get; set; }
public DbSet<Category> Categories { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ProvinceMap());
modelBuilder.Configurations.Add(new CategoryMap());
}
}
}
DropCreateDatabaseIfModelChanges<PortalContext>()太暴力了

Code First数据库迁移

改变原来类的结构后数据库将发生错误提示

1.第一次建立数据库迁移通过nugget来进行编辑

Package Manager Console-》Enable-Migrations -StartUpProjectName CodeFirst-》执行“Add-Migration FirstMigration”命令-》

执行“Update-Database”命令,更新数据库架构

你的项目中将自动生成一个名为”Migrations“的文件夹,里面包含两个文件: Configuration.cs和201308211510117_InitialCreate.cs(201308211510117是时间戳)。

Configuration.cs:是迁移配置代码,一般我们不需要修改。

namespace CodeFirst.Migrations
{
using System;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq; internal sealed class Configuration : DbMigrationsConfiguration<CodeFirst.OrderContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
} protected override void Seed(CodeFirst.OrderContext context)
{
// This method will be called after migrating to the latest version. // You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}

201308211510117_InitialCreate.cs:以代码的形式记录了本地数据库的表结构定义。

设置自动迁移

有以下两个参数可以对自动迁移进行设置: 
1. AutomaticMigrationsEnabled:获取或设置 指示迁移数据库时是否可使用自动迁移的值。 
2. AutomaticMigrationDataLossAllowed:获取或设置 指示是否可接受自动迁移期间的数据丢失的值。如果设置为false,则将在数据丢失可能作为自动迁移一部分出现时引发异常。

原文:

http://www.mamicode.com/info-detail-872834.html

http://www.cnblogs.com/liupeng/p/4797046.html

http://www.guanggua.com/question/21573550-setting-unique-constraint-with-fluent-api.html

https://msdn.microsoft.com/en-us/data/jj591617.aspx#PropertyIndex

http://www.cnblogs.com/lyq2012/p/6183895.html

EF使用Fluent API配置映射关系的更多相关文章

  1. 使用 Fluent API 配置/映射属性和类型(摘自微软Data Access and Storage)

    使用 Fluent API 配置/映射属性和类型 使用实体框架 Code First 时,默认行为是使用一组 EF 中内嵌的约定将 POCO 类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体 ...

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

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

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

    使用 Fluent API 配置/映射属性和类型 使用实体框架 Code First 时,默认行为是使用一组 EF 中内嵌的约定将 POCO 类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体 ...

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

    1.将多个实体类映射到数据库中的一个表 要将多个实体映射到一个数据库表需要满足: a. 两个实体必须是一对一关系 b.两个实体共享一个主键 public class MyContext:DbConte ...

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

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

  6. 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 ...

  7. Code First约定-Fluent API配置

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

  8. EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射

    I.EF里的默认映射 上篇文章演示的通过定义实体类就可以自动生成数据库,并且EF自动设置了数据库的主键.外键以及表名和字段的类型等,这就是EF里的默认映射.具体分为: 数据库映射:Code First ...

  9. EF——默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射 02 (转)

    EF里的默认映射以及如何使用Data Annotations和Fluent API配置数据库的映射   I.EF里的默认映射 上篇文章演示的通过定义实体类就可以自动生成数据库,并且EF自动设置了数据库 ...

随机推荐

  1. Web API中的模型验证

    一.模型验证的作用 在ASP.NET Web API中,我们可以使用 System.ComponentModel.DataAnnotations 命名空间中的属性为模型上的属性设置验证规则. 一个模型 ...

  2. System.ComponentModel.DataAnnotations.Schema.TableAttribute 同时存在于EntityFramework.dll和System.ComponentModel.DataAnnotations.dll中

    Entity Framework 与 .net4.5 的 System.ComponentModel.DataAnnotations 都有 System.ComponentModel.DataAnno ...

  3. vuex中strict严格模式

    开启严格模式,仅需在创建 store 的时候传入strict: true const store = new Vuex.Store({ state, strict:true//开启严格模式后,只能通过 ...

  4. 网易PM599产品笔试题

    前几天做了网易PM599的云计算领域产培生的笔试题目,下面整理了一下各个方向的笔试题和我对这些题目的解答. 云计算领域: 1.对工业互联网的理解,结合自身优势谈谈自己应该怎么去创业. 工业互联网是一次 ...

  5. 开发mis系统需要的技术

    一.b/s架构 b/s架构:就broser/server,浏览器/服务器的说法.服务器端要运行tomcat,提供链接数据库服务供java代码读写数据,这个可以在eclipse中配置运行.浏览器则解释j ...

  6. matplotlib-形状

    需要   import matplotlib.patches as mp import numpy as np import matplotlib.pyplot as plt import matpl ...

  7. php serialize(),unserialize()

    序列化serialize()与反序列化unserialize(): 序列化serialize():就是将一个变量所代表的 “内存数据”转换为“字符串”的形式,并持久保存在硬盘(写入文件中保存)上的一种 ...

  8. Coursera, Big Data 1, Introduction (week 1/2)

    Status: week 2 done. Week 1, 主要讲了大数据的的来源 - 机器产生的数据,人产生的数据(比如社交软件上的update, 一般是unstructed data), 组织产生的 ...

  9. Kaldi的关键词搜索(Keyword Search,KWS)

    本文简单地介绍了KWS的原理--为Lattice中每个词生成索引并进行搜索:介绍了如何处理OOV--替补(Proxy,词典内对OOV的替补)关键词技术:介绍了KWS的语料库格式:介绍了KWS在Kald ...

  10. python之MD5加密

    一. MD5加密import hashlib #Python3里的引用#import md5 #Python2里的引用 1. md5是不可逆的,不能解密2. 所有语言生成的md5串都是一样的 3. 不 ...