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. bzoj5153&uoj348 【WC2018】州区划分

    五十分就是裸的O(3^n)子集dp. $$f[S]*{w[S]^{p}}=\sum_{T \in S}{f[T]*{w[S-T]^{p}}}$$ 然后我们考虑优化这个dp,我们发现这是子集卷积的形式, ...

  2. 去除vue项目中的#及其ie9兼容性

    一.如何去除vue项目中访问地址的# vue2中在路由配置中添加mode(vue-cli创建的项目在src/router/index.js) export default new Router({ m ...

  3. 【爆料】-《亚伯大学毕业证书》Aber一模一样原件

    ☞亚伯大学毕业证书[微/Q:865121257◆WeChat:CC6669834]UC毕业证书/联系人Alice[查看点击百度快照查看][留信网学历认证&博士&硕士&海归&am ...

  4. Spring py登陆模块(包含 记录登陆时间,记录ip,增加积分)

    嘛基于最近的复习准备写个关于spring登陆模块的小程序 虽然小但是五脏俱全呐 话不多说让我来介绍一下今天的登陆程序. 这些是 基于Spring JDBC 的持久层实现 基于Spring 声明事物的业 ...

  5. MIP 内容声明

    从搜索结果页点出的 MIP 页面,其页面上的任何内容(包括但不限于广告.在线咨询.统计等组件)均视为在原站点上的投放和使用. MIP (Mobile Instant Pages - 移动网页加速器), ...

  6. 启动VMware虚拟机时总是出现许可证到期提示怎么办?

    不知道大家有没有遇到过这个问题,每次当你打开VMware虚拟机时它总是会提示许可证到期,需要注册,还会出现许多报红的代码,下面就让小编带大家解决一下吧~ VMware教程 如果Fusion本身无法启动 ...

  7. .NET中的状态机库Stateless

    标题:.NET中的状态机库Stateless 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/10674018.html 介绍 什么是状态机和状态模式 ...

  8. 结合Mybatis源码看设计模式——外观模式

    定义 提供了一个统一的接口,用来访问子系统中一群接口 适用场景 子系统复杂,增加外观模式提供简单调用接口 构建多层系统结构,用外观对象作为每层入口 详解 外观模式,主要理解外观.通俗一点可以认为这个模 ...

  9. HTML基础系列

    HTML标记语言,网页制作的第一步. 什么是HTML呢?查百度 基础语法 常用标签 HTML是超文本标记语言,HTML不用编译,直接在浏览器中执行,HTML是一个文本文件. HTML基本结构,标签,元 ...

  10. jQuery AJAX与jQuery事件的分析讲解

    jQuery 本身即是为事件处理而特别设计的,jQuery 事件处理方法是 jQuery 中的核心函数. $(function() { ... }); 是如下格式的缩写: ? 1 $(document ...