Code First的数据库映射

有两种方式来实现数据库映射:

  • 数据属性:Data Annotation
  • 映射配置: Fluent API

有继承关系的实体如何映射?

  • Code First在生成数据库表时,默认使用TPH方式

就是把父类和子类生成同一张表,额外增加了一列Discriminator字段,区分是父类或子类的数据类型

比如:

父类Book对象

public class Book
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int BookID { get; set; }
public string BookName { get; set; }
public int Pages { get; set; }
}

子类HistoryBooks对象,继承Book

public class HistoryBooks:Book
{
public int Chapter { get; set; }
}

数据库生成一张表

  • 另一种方式(Data Annotation实现):TPT

不管父类子类,各自生成一张表,以及在子类中增加两者联系的外键;

定义TPT方式 父类和子类定义 [Table("XXX")]

如:

父类

[Table("Book")]
public class Book
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int BookID { get; set; }
public string BookName { get; set; }
public int Pages { get; set; }
}

子类

[Table("HistoryBooks")]
public class HistoryBooks:Book
{public int Chapter { get; set; }
}

映射数据生成的两张表

Book:

HistoryBooks:

映射方式一:Data Annotation

给实体对象的属性加上注解特性,实现与数据库之间建立映射关系并进行控制

如:

Booid映射到表中字段为自增的主键

DataAnnotations 包含的常用特性:

KeyAttribute:对应数据库中表的主键的设置

RequiredAttribute:对应数据库中字段的数据不可null

MaxLengthAttribute:对应数据库中字符串类型字段的最大长度

ConcurrencyCheckAttribute:指定用于开放式并发检查的列的数据类型

TimestampAttribute:将列的数据类型指定为行版本

DatabaseGeneratedAttribute:标记指定实体属性是由数据库生成的,并指定生成策略(None数据库不生成值,Identity当插入行时,数据库生成值,Computed当插入或更新行时,数据库生成值)

TableAttribute:指定实体类对应的数据表名

ColumnAttribute:指定实体属性在数据库中的列名

ForeignKeyAttribute :指定导航属性的外键字段

NotMappeAttribute:不映射对应字段

映射方式二:Fluent API

Fluent API的配置方式可以将实体类与映射配置进行解耦合

有两种方式来实现Fluent API的映射配置

  • 第一种:重写Dbcontext的中OnModelCreating方法

如下面的Book类,不再有Data Annotation特性

public class Book
{
public int BookID { get; set; }
public string BookName { get; set; }
public int Pages { get; set; }
}

重写Dbcontext中的OnModelCreating方法实现Book类映射的配置:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Book>().HasKey(t => t.BookID); base.OnModelCreating(modelBuilder);
}

现实项目中,实体对象可能是非常多的,在OnModelCreating方法中逐一进行映射配置,可想而知会造成Dbcontext的代码庞大。

  • 第二种:新建BookMap类,并继承EntityTypeConfiguration<EntityType>

1、在新建的BookMap类实现映射配置

public class BookMap : EntityTypeConfiguration<Book>
{
public BookMap()
{
this.ToTable("Book", "dbo");
this.HasKey(p => p.BookID);
//this.HasKey(p => new { p.BookID, p.BookPreID });//关联主键
this.Property(p => p.BookID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);//自动生成
this.Property(p => p.BookName).IsRequired().HasMaxLength().HasColumnName("BookName").IsUnicode(false);//非空,最大长度20,自定义列名,列类型为varchar而非nvarchar
this.Ignore(p => p.BookDescription);//忽略改属性的映射
}
}

2、依旧重写Dbcontext中的OnModelCreating方法,将BookMap 类的实例添加到modelBuilder的Configurations。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new BookMap());
}

这样能大大减少OnModelCreating的代码量,依然存在一个问题,就是实体对象一多,还是要逐条将Map类的实例添加到modelBuilder的Configurations

3、利用反射将程序集中所有的EntityTypeConfiguration添加到modelBuilder.Configurations中,可以说完全解耦了

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
}

注:此段代码源自网友文章,摘自nopCommerce项目的代码  连接

Entity Framework 查漏补缺 (三)的更多相关文章

  1. Entity Framework 查漏补缺 (一)

    明确EF建立的数据库和对象之间的关系 EF也是一种ORM技术框架, 将对象模型和关系型数据库的数据结构对应起来,开发人员不在利用sql去操作数据相关结构和数据.以下是EF建立的数据库和对象之间关系 关 ...

  2. Entity Framework 查漏补缺 (二)

    数据加载 如下这样的一个lamda查询语句,不会立马去查询数据库,只有当需要用时去调用(如取某行,取某个字段.聚合),才会去操作数据库,EF中本身的查询方法返回的都是IQueryable接口. 链接: ...

  3. 【Android面试查漏补缺】之事件分发机制详解

    前言 查漏补缺,查漏补缺,你不知道哪里漏了,怎么补缺呢?本文属于[Android面试查漏补缺]系列文章第一篇,持续更新中,感兴趣的朋友可以[关注+收藏]哦~ 本系列文章是对自己的前段时间面试经历的总结 ...

  4. js基础查漏补缺(更新)

    js基础查漏补缺: 1. NaN != NaN: 复制数组可以用slice: 数组的sort.reverse等方法都会改变自身: Map是一组键值对的结构,Set是key的集合: Array.Map. ...

  5. 20165223 week1测试查漏补缺

    week1查漏补缺 经过第一周的学习后,在蓝墨云班课上做了一套31道题的小测试,下面是对测试题中遇到的错误的分析和总结: 一.背记题 不属于Java后继技术的是? Ptyhon Java后继技术有? ...

  6. Mysql查漏补缺笔记

    目录 查漏补缺笔记2019/05/19 文件格式后缀 丢失修改,脏读,不可重复读 超键,候选键,主键 构S(Stmcture)/完整性I(Integrity)/数据操纵M(Malippulation) ...

  7. Django 查漏补缺

    Django 查漏补缺 Django  内容回顾: 一. Http 请求本质: 网络传输,运用socket Django程序: socket 服务端 a. 服务端监听IP和端口 b. 浏览器发送请求 ...

  8. Mysql查漏补缺

    Mysql查漏补缺 存储引擎 数据库使用存储引擎来进行CRUD的操作,不同的存储引擎提供了不同的功能.Mysql支持的存储引擎有InnoDB.MyISAM.Memory.Merge.Archive.F ...

  9. Java查漏补缺(3)(面向对象相关)

    Java查漏补缺(3) 继承·抽象类·接口·静态·权限 相关 this与super关键字 this的作用: 调用成员变量(可以用来区分局部变量和成员变量) 调用本类其他成员方法 调用构造方法(需要在方 ...

随机推荐

  1. 「SDOI 2018」反回文串

    题目大意: 求字符集大小为$k$长度为$n$的经循环移位后为回文串的数量. 题解: 这题是D1里最神的吧 考虑一个长度为$n$回文串,将其循环移位后所有的串都是满足要求的串. 但是显然这样计算会算重. ...

  2. 51nod_1412_AVL树的种类_动态规划

    51nod_1412_AVL树的种类_动态规划 题意: 平衡二叉树(AVL树),是指左右子树高度差至多为1的二叉树,并且该树的左右两个子树也均为AVL树. 现在问题来了,给定AVL树的节点个数n,求有 ...

  3. python常见的报错提示

    在运行或编写一个程序时常会遇到错误异常,这时python会给你一个错误提示类名,告诉出现了什么样的问题(Python是面向对象语言,所以程序抛出的异常也是类).能很好的理解这些错误提示类名所代表的意思 ...

  4. 基于 Webpack 4 和 React hooks 搭建项目

    面对日新月异的前端,我表示快学不动了

  5. asp.net core 3.0 gRPC框架小试

    什么是gRPC gRPC是google开源的一个高性能.跨语言的RPC框架,基于HTTP2协议,采用ProtoBuf 定义的IDL. gRPC 的主要优点是: 现代高性能轻量级 RPC 框架. 协定优 ...

  6. .NET Core使用Quartz执行调度任务进阶

    一.前言运用场景 Quartz.Net是一个强大.开源.轻量的作业调度框架,在平时的项目开发当中也会时不时的需要运用到定时调度方面的功能,例如每日凌晨需要统计前一天的数据,又或者每月初需要统计上月的数 ...

  7. 版本号对比 -- Python实现

    相同位数版本号大小比较: def abc(str1, str2): if str1 == "" or str2 == "": print("输入包含空 ...

  8. 使用WebGL 自定义 3D 摄像头监控模型

    前言 随着视频监控联网系统的不断普及和发展, 网络摄像机更多的应用于监控系统中,尤其是高清时代的来临,更加快了网络摄像机的发展和应用. 在监控摄像机数量的不断庞大的同时,在监控系统中面临着严峻的现状问 ...

  9. asp.net core系列 29 EF模型配置(查询类型,关系数据库建模)

    一.查询类型 此功能是EF Core 2.1中的新功能. EF Core除了实体类型之外,EF Core模型还可以包含查询类型,这些查询类型是针对“未映射到实体类型”的数据获取.比如视图,或只读数据表 ...

  10. Java开发环境Jave EE 和 jdk 下载

    以下软件均为64位环境 jdk版本:jdk1.8.0_181 jave EE版本(当前最新版本4.8):eclipse-jee-photon-R-win32-x86_64.zip 链接:https:/ ...