定义一个继承自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. JDK动态代理和CGLIB代理的区别

    一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件 ...

  2. eclipse将javaSE项目导出成可执行jar包

    将第三方包和项目打包到一块 step1:选中要导出的项目,右键选择Export step2:选择java/Runable JAR file step3:选择main主程序,选择第三方包打包的形式,推荐 ...

  3. SQL的六种约束

    https://blog.csdn.net/z120270662/article/details/79501621

  4. mysql load_file在数据库注入中使用

    load_file函数只有满足两个条件就可以使用: 1.文件权限:chmod a+x pathtofile 2.文件大小: 必须小于max_allowed_packet 例子: select load ...

  5. C# FTPHelper工具类

    /// <summary> /// Ftp /// </summary> public class FtpFileOperation { private string _ftp ...

  6. Eclipse下生成/编辑Java类图或时序图(UML)[转载]

    一 引用文章 1.[eclipse下生成Java类图和时序图,生成UML图(更完整版)](https://blog.csdn.net/guomainet309/article/details/5302 ...

  7. luogu P4931 情侣?给我烧了!

    双倍经验 传送门 首先坐在一起的cp和不坐在一起的cp是相对独立的,可以分开考虑,然后方案数相乘 坐在一起的cp,方案为\(\binom{n}{k}*\binom{n}{k}*k!*2^k\).首先选 ...

  8. 第25月25日 urlsession

    1. private lazy var session: URLSession = { let configuration = URLSessionConfiguration.default conf ...

  9. 5.21http网页基础

    1,HTML的由来: web网页开发的标准,由w3c万维网联盟组织制定的.是制作网页的规范标准,分为结构标准.表现标准.行为标准.结构:html.表现:css.行为:Javascript. 2,htm ...

  10. js原生事件

    js原生事件封装 // 事件处理对象 var EventUtil = { // 添加事件监听 add: function(element, type, callback){ if(element.ad ...