针对关系型数据库,实体之间的关系最常见的就是通过外键关联的一对一、一对多和多对多的关系,新的EF Core通过注释和Fluent API 能够做到接近于数据库通过DML创建模型的效果了。实际上,通过DML 最大的优势在于,能够定义所谓的Independent/Dependent Entity具体的那个字段作为关联字段,而EF更多通过一种约定去描述这种关联关系,不过通过Fluent API 能够收工定义的操作范围更近广了。

下面的这个表关系实际上描述了大部分关系型数据库的关联关系,能够覆盖大部分场景,通过这个例子去说明Code First 创建实体的标准方法。

Members 和Tasks 关系,Member是Independent Entity, Tasks是Dependent Entity,定义类如下:

namespace MemberTask.Models
{
public partial class Members
{
[Key]
public int? MemberId { get; set; }
public string MemberName { get; set; }
[InverseProperty("Members")]
public List<Tasks> Tasks { get; set; } }
}
namespace MemberTask.Models
{
public partial class Tasks
{
[Key]
public int? TaskId { get; set; }
public int TaskName { get; set; }
public int MemberId { get; set; }
[ForeignKey("MemberId")]
public Members Members { get; set; }
//part of many2many
[InverseProperty("Task")]
public List<TaskAndOaTasksR> TaskAndOaTasksRs { get; set; }
}
}

在这两个实体的关系中:

先看Tasks类(红色字体部分),通过注释指明,MemberId 字段作为外键,而Members引用导航属性,作为外键所关联依赖的对象。

Members类,Tasks 列表导航属性就是被引用对象,而注释表明Members 就是Tasks中的引用导航属性Members。

另外3个实体店关系为,Tasks和OaTasks是业务实体,TaskAndOaTasksRs实际上作为一个中间表,提供一种多对多的关系,这种模式实际上是作为灵活的一种实体模式,虽然有一定的空间损耗,但是无论哪种关系,或者未来需要扩展成为多对多的关系可以随时实施。

OaTasks:

namespace MemberTask.Models
{
public partial class OaTasks
{
[Key]
public int? OaTaskId { get; set; }
public string OaTaskName { get; set; }
[InverseProperty("OaTask")]
public List<TaskAndOaTasksR> TaskAndOaTasksRs { get; set; } }
}

TasksAndOaTasksRs:

namespace MemberTask.Models
{
public partial class TaskAndOaTasksR
{
public int? TaskId { get; set; }
[ForeignKey("TaskId")]
public Tasks Task { get; set; }
[ForeignKey("OaTaskId")]
public int? OaTaskId { get; set; }
public OaTasks OaTask { get; set; } }
}

TasksAndOaTasksRs在实际上使用的时候,是不需要实现TaskId查询关联的多个OaTaskId的,仅仅查询TaskId & OaTaskId  的一一对应关系,因此通过引用导航属性引用Tasks 和OaTasks。相反,Tasks 和OaTasks都有需要进行一对多关联查询,因此采用了列表导航属性。

模型建好后,根据实际情况配置DbContext,特别是针对外键关联,根据实际情况定义好OnDelete方法。

        protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Members>()
.Property(b => b.MemberId).ValueGeneratedNever();
modelBuilder.Entity<Tasks>()
.Property(t => t.TaskId).ValueGeneratedNever();
modelBuilder.Entity<OaTasks>()
.Property(o => o.OaTaskId).ValueGeneratedNever(); modelBuilder.Entity<Tasks>()
.HasOne(m=>m.Members)
.WithMany(t=>t.Tasks)
.OnDelete(DeleteBehavior.Cascade); // below is for many2many
modelBuilder.Entity<TaskAndOaTasksR>()
.HasOne(t => t.Task)
.WithMany(tt => tt.TaskAndOaTasksRs); modelBuilder.Entity<TaskAndOaTasksR>()
.HasOne(t => t.OaTask)
.WithMany(tt => tt.TaskAndOaTasksRs); modelBuilder.Entity<TaskAndOaTasksR>()
.HasKey(t => new {t.TaskId, t.OaTaskId}); }

运行数据库更新命令,实体和数据库模型就建好了。

EF Core创建实体的Code First标准方法的更多相关文章

  1. ASP.NET Core 中使用EF Core 将实体映射到数据库表的方法(SQL Server)

    前段时间听过一个关于使用ASP.NET Core建立项目的视频.其中使用EF Core映射到数据库的部分是按部就班地学习.今天自己建立项目时,有些步骤已经有一些遗忘.所以写下这篇文章,顺便理清思路. ...

  2. EF Core For Oracle11中Find FirstOrDefault等方法执行失败

    问题描述 最近在使用ef core连接oracle的发现Find.FirstOrDefault.Skip Task分页等等方法执行失败.使用的是docker安装的oracle11,错误如下图: 解决办 ...

  3. EF Core开发模式之Code First

    Code First顾名思义,代码为先.首先编写完相关的实体类及DbContext派生类,然后通过映射关系自动在数据库中完成数据库表的创建. 本例中创建一个班级和学生的管理,主要有班级类MyClass ...

  4. ASP.NET Core中使用EF Core(MySql)Code First

    ⒈添加依赖 MySql.Data.EntityFrameworkCore ⒉在appsettings.json配置文件中配置数据库连接字符串 { "Logging": { &quo ...

  5. EF Core 中DbContext不会跟踪聚合方法和Join方法返回的结果,及FromSql方法使用讲解

    EF Core中: 如果调用Queryable.Count等聚合方法,不会导致DbContext跟踪(track)任何实体. 此外调用Queryable.Join方法返回的匿名类型也不会被DbCont ...

  6. 张高兴的 Entity Framework Core 即学即用:(一)创建第一个 EF Core 应用

    写在前面 Entity Framework Core (EF Core) 是 .NET 平台流行的对象关系映射(ORM)框架.虽然 .NET 平台中 ORM 框架有很多,比如 Dapper.NHibe ...

  7. [翻译 EF Core in Action 2.2] 创建应用程序的数据库上下文

    Entity Framework Core in Action Entityframework Core in action是 Jon P smith 所著的关于Entityframework Cor ...

  8. EF Core 快速上手——创建应用的DbContext

    系列文章 EF Core 快速上手--EF Core 入门 EF Core 快速上手--EF Core的三种主要关系类型 本节导航 定义应用的DbContext 创建DbContext的一个实例 创建 ...

  9. EF Core 2.0中如何手动映射数据库的视图为实体

    由于Scaffold-DbContext指令目前还不支持自动映射数据库中的视图为实体,所以当我们想使用EF Core来读取数据库视图数据的时候,我们需要手动去做映射,本文介绍如何在EF Core中手动 ...

随机推荐

  1. centos配置备忘(apache\php\mysql)

    1. 安装apache\php\mysql=======================================yum -y install httpd php mysql mysql-ser ...

  2. 【NIFI】 开发自定义Nifi Processor

    本例需要基础知识:[NIFI] Apache NiFI 安装及简单的使用 Nifi不光可以使用自带的Processor,还可以自定义Processor.本例简单介绍开发一个Processor 开发 1 ...

  3. java学习第四周

    这是暑假第四周,这周我继续学习了Java的基础知识. 了解到Java的类继承,学习到Java的接口的相关知识Java的每一个类都有且仅有一个直接父类,没有多重继承,但是接口可以继承多个,如果把接口看做 ...

  4. 如何将本地代码通过git上传到码云

    ps:同部署到GitHub上一样 http://www.cnblogs.com/pcx105/p/7777932.html

  5. hdu-1041(大数模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1041 题意:电脑中存在数字1,进行扩展操作,如果遇到1变为“01”,如果遇到0,变为“10”,经过一次 ...

  6. C#创建、设置和安装Windows服务

    文章大部分内容转自:http://www.cnblogs.com/greatandforever/archive/2008/10/14/1310504.html:和:http://www.cnblog ...

  7. i2c总线,核心,驱动详解

    Linux I2C驱动分析(一)----I2C架构和总线驱动 一.I2C总线原理 I2C是一种常用的串行总线,由串行数据线SDA 和串线时钟线SCL组成.I2C是一种多主机控制总线,它和USB总线不同 ...

  8. 1.gil全局解释器锁, 2. 死锁与递归锁 3. 信号量 4. Event事件 5. 线程queue

    gil本质就是一把互斥锁,相当于执行权限,每个进程都会存在一把gil,同一进程内的多个线程必须抢到gil 之后才能使用cpython解释器来执行自己的代码,同一进程下的多线程不能并行,但可以实现并发 ...

  9. android-基础编程之开篇

    先唠叨两句,机缘巧合现在来做android开发了,之前做后台c的,对这块不是很了解,要慢慢学习,对于framework层的学习感觉需要app开发经验更好点,在完成工作之余积累一些基础知识.既来之则安之 ...

  10. JS鼠标滚动插件scrollpath使用介绍

    JS鼠标滚动插件scrollpath:在这个插件中首先要引人的JS是jQuery,因为后面的JS都是基于它的.再者需要引入的是jquery.scrollpath.js.scrollpath.css还有 ...