EF Codefirst 多对多关系 操作中间表的 增删改查(CRUD)

 

前言

此文章只是为了给新手程序员,和经验不多的程序员,在学习ef和lambada表达式的过程中可能遇到的问题。

本次使用订单表和员工表建立多对多关系。

首先是订单表:

public class Order
{
public int OrderId { get; set; } public string OrderTitle { get; set; } public string CustomerName { get; set; } public DateTime TransactionDate { get; set; } [ConcurrencyCheck]
[Timestamp]
public byte[] TimeStamp { get; set; } public virtual ICollection<Employee> InvolvedEmployees { get; set; }
}

接下来是员工表:

public class Employee
{
public int EmployeeId { get; set; } public string EmployeeName { get; set; } public virtual ICollection<Order> Orders { get; set; }
}

映射文件(mapping):

public class OrderMap:EntityTypeConfiguration<Order>
{
public OrderMap()
{
this.HasKey(o => o.OrderId);
//OrderId为自增长
this.Property(o => o.OrderId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(o => o.OrderTitle).IsRequired().HasMaxLength(64);//订单名称为必填,最大长度为64;
this.Property(o => o.CustomerName).IsRequired().HasMaxLength(64);//订单名称为必填,最大长度为64;
this.Property(o => o.TransactionDate).IsRequired(); //订单名称为必填,最大长度为64;
}
}
public class EmployeeMap:EntityTypeConfiguration<Employee>
{
/// <summary>
/// 构造函数
/// </summary>
public EmployeeMap()
{
this.HasKey(x => x.EmployeeId);
this.ToTable("Employees");
this.Property(x => x.EmployeeName).IsRequired().HasMaxLength(20); //设置多对多的关系 .Map()配置用于存储关系的外键列和表。
/*
Employees HasMany此实体类型配置一对多关系。对应Orders实体
WithMany 将关系配置为 many:many,且在关系的另一端有导航属性。
* MapLeftKey 配置左外键的列名。左外键指向在 HasMany 调用中指定的导航属性的父实体。
* MapRightKey 配置右外键的列名。右外键指向在 WithMany 调用中指定的导航属性的父实体。
*/
this.HasMany(x => x.Orders).
WithMany(x => x.InvolvedEmployees).
Map(m => m.ToTable("EmployeeOrder").
MapLeftKey("EmployeeId").
MapRightKey("OrderId"));
}
}

dbcontext文件:

public class EfCodeFirstWithManyDbContext:DbContext

    {
public EfCodeFirstWithManyDbContext()
: base("DefaultConnection")
{ } public IDbSet<Order> Orderses { get; set; }
public IDbSet<Employee> Employeees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new OrderMap());
modelBuilder.Configurations.Add(new EmployeeMap());
base.OnModelCreating(modelBuilder);
}
}

生成数据库:

数据库关系图:

基础工作建立完毕。

正文:

我们都知道在codefirst 配置多对多关系的时候,会自动给我买生成中间表。

在modelfirst和datafirst的时候都会生成一个中间类:EmployeeOrder.cs

而codefirst不会生成这个类,本文所阐述的就是使用在codefirst中使用ef、lambada表达对其进行增删改查的多种情况

  1. 创建一个订单

  2. 添加订单信息、员工信息到数据表中,建立两则多对多的联系

  3. 清空中间表之间的数据,而不影响employee和order表中的数据

  4. 给中间表添加数据,给两个已经存在的数据建立中间关系

  5. 操作中间表,修改两个表employee和order中值,并且删除中间表中多余的值

本文大概操作次5种情况。

代码:

//添加订单信息、员工信息到数据表中,建立两则多对多的联系
public static void CreateFullOrderByEmployee()
{
#region 添加订单信息、员工信息到数据表中,建立两则多对多的联系 using (var dbContext = new EfCodeFirstWithManyDbContext())
{
var order = new Order
{
OrderTitle = "购买汽车",
CustomerName = "梁桐铭",
TransactionDate = DateTime.Now,
InvolvedEmployees = new List<Employee>()
};
var employee1 = new Employee {EmployeeName = "管理员-yoyocms", Orders = new List<Order>()};
var employee2 = new Employee {EmployeeName = "主管-yoyocms", Orders = new List<Order>()};
//先保存订单到数据库中
dbContext.Orderses.Add(order); order.InvolvedEmployees.Add(employee1);
//order.InvolvedEmployees.Add(employee2); // employee2.Orders.Add(order);
var res = dbContext.SaveChanges();
} #endregion
}

为了测试方便对这个方法for循环了20次:

private static void Main(string[] args)
{ for (int i = 0; i < 20; i++)
{
CreateFullOrderByEmployee();
} Console.WriteLine("加载完毕,请点击任意键退出");
Console.ReadKey();
}

清空中间表信息,而不影响order表和employee表的信息

//清空两个中间表之间的关系
public static void EmptyEmployeeOrder()
{
using (var dbContext = new EfCodeFirstWithManyDbContext())
{
//获取到employeeId为20下,所有Orders订单列表信息和员工信息。
var employeeToUpdate =
dbContext.Employeees.Include(x => x.Orders).FirstOrDefault(x => x.EmployeeId == 20);
if (employeeToUpdate != null)
{
employeeToUpdate.Orders = new List<Order>();
dbContext.SaveChanges();
}
else
{
Console.WriteLine("查询失败EmptyEmployeeOrder为空");
}
}
}

建立员工表和对应的订单表中建立两个表之间的联系

//建立两个已经存在的数据建立中间关系
public static void AddInfoEmployeeOrder()
{
using (var dbContext = new EfCodeFirstWithManyDbContext())
{
//获取到employeeId为20下,所有Orders订单列表信息和员工信息。
var employeeToAdd = dbContext.Employeees.Include(x => x.Orders).FirstOrDefault(x => x.EmployeeId == 20);
//设计订单表的集合,将新增的数据填充进来
int[] orderIdList = {13, 14, 15, 16, 17, 18, 19};
//判断employeeToAdd.Orders中是否有重复的OrderId
if (employeeToAdd != null)
{
//查询出目前员工对应的订单表
var employeeOrder = new HashSet<int>(employeeToAdd.Orders.Select(e => e.OrderId)); foreach (var order in dbContext.Orderses)
{
//即将要添加orderIdList值的是否包含订单表的id
//筛选出orderidList和orders中共同的值,添加到order.OrderId
if (orderIdList.Contains(order.OrderId))
{
//查询出目前employee表中的orderId是否包含了orderIdList中的id
if (employeeOrder.Contains(order.OrderId))
{
//打印出重复的orderId
Console.WriteLine("重复的ID为" + order.OrderId);
Console.WriteLine("不执行添加结果");
}
else
{
//打印出Employee表中没有orderId
Console.WriteLine("即将添加的值" + order.OrderId);
//添加重复的值
employeeToAdd.Orders.Add(order);
}
}
}
}
else
{
Console.WriteLine("employeeToAdd信息为空");
} dbContext.SaveChanges();
}
}

修改两个表employee和order中值,并且删除多余的值

/// <summary>
/// 修改两个表employee和order中值,并且删除多余的值
/// </summary>
public static void UpdateInfoEmployeeOrder()
{
//首先获取到EmployeeId=20中,所有的Orders列表和employee信息
using (var dbContext = new EfCodeFirstWithManyDbContext())
{
var employeeUpdate =
dbContext.Employeees.Include(x => x.Orders).FirstOrDefault(x => x.EmployeeId == 20);
//需要更改对应的OrderId列表
int[] orderIdList = {13, 14, 15, 16, 17, 18, 19}; if (employeeUpdate != null)
{
//获取employee中的OrderIdlist
var employeeOrderIdList = new HashSet<int>(employeeUpdate.Orders.Select(e => e.OrderId));
foreach (var order in dbContext.Orderses)
{
//判断要修改的Orderid和Orders表中的均包含
if (orderIdList.Contains(order.OrderId))
{
if (!employeeOrderIdList.Contains(order.OrderId))
{
Console.WriteLine("修改对应的订单Id表" + order.OrderId);
employeeUpdate.Orders.Add(order);
}
}
else
{
if (employeeOrderIdList.Contains(order.OrderId))
{
Console.WriteLine("删除无用的订单表id"+order.OrderId);
employeeUpdate.Orders.Remove(order);
}
}
}
}
else
{
Console.WriteLine("查无employeeUpdate 的信息");
} dbContext.SaveChanges();
}
}

尾声

至此操作实现了对codefirst中,对中间表的CRUD过程。

源代码下载


来源:https://www.cnblogs.com/wer-ltm/p/4944745.html

EF Codefirst 中间表(关系表)的增删改查(转)的更多相关文章

  1. 一、数据库表中字段的增删改查,二、路由基础.三、有名无名分组.四、多app共存的路由分配.五、多app共存时模板冲突问题.六、创建app流程.七、路由分发.八、路由别名,九、名称空间.十、反向解析.十一、2.x新特性.十二、自定义转换器

    一.数据库表中字段的增删改查 ''' 直接在modules中对字段进行增删改查 然后在tools下点击Run manage.py Task执行makemigrations和migrate 注意在执行字 ...

  2. Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查

    一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...

  3. 第三百零七节,Django框架,models.py模块,数据库操作——表类容的增删改查

    Django框架,models.py模块,数据库操作——表类容的增删改查 增加数据 create()方法,增加数据 save()方法,写入数据 第一种方式 表类名称(字段=值) 需要save()方法, ...

  4. 五 Django框架,models.py模块,数据库操作——表类容的增删改查

    Django框架,models.py模块,数据库操作——表类容的增删改查 增加数据 create()方法,增加数据 save()方法,写入数据 第一种方式 表类名称(字段=值) 需要save()方法, ...

  5. mysql对库,表及记录的增删改查

    破解密码 #1.关闭mysqlnet stop mysqlmysql还在运行时需要输入命令关闭,也可以手动去服务关闭 #2.重新启动mysqld --skip-grant-tables跳过权限 #3m ...

  6. Oracle学习总结_day01_day02_表的创建_增删改查_约束

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 更新: SELECT * FROM (SELECT R ...

  7. Java代码自动生成,生成前端vue+后端controller、service、dao代码,根据表名自动生成增删改查功能

    本项目地址:https://github.com/OceanBBBBbb/ocean-code-generator 项目简介 ocean-code-generator采用(适用):     ,并使用m ...

  8. 表结构修改以及sql增删改查

    修改表结构 修改表名 alter table 表名 rename 新名 增加字段 alter table 表名 add 字段名 数据类型 约束 删除字段 alter table 表名 drop 字段名 ...

  9. 如何搭建一个WEB服务器项目(二)—— 对数据库表进行基本的增删改查操作

    使用HibernateTemplate进行增删改查操作 观前提示:本系列文章有关服务器以及后端程序这些概念,我写的全是自己的理解,并不一定正确,希望不要误人子弟.欢迎各位大佬来评论区提出问题或者是指出 ...

  10. hibernate课程 初探单表映射3-5 hibernate增删改查

    本节简介: 1 增删改查写法 2 查询load和查询get方法的区别 3 demo 1 增删改查写法 增加 session.save() 修改 session.update() 删除 session. ...

随机推荐

  1. FPGA计算中定标与位扩展的实现

    我不知道名字取对没有,在FPGA计算中有时往往需要在不溢出的情况下将数扩大,从而获得更好的计算精度. 比如.在一个8位宽的系统中,将x=0000_0010,算术左移m=5位之后得到xt=0100_00 ...

  2. Ftp主动模式和被动模式以及java连接ftp模式设置

    Ftp主动模式和被动模式以及java连接ftp模式设置 https://www.cnblogs.com/huhaoshida/p/5412615.html (1) PORT(主动模式) PORT中文称 ...

  3. 升讯威微信营销系统开发实践:(2)中控服务器的详细设计( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  4. My Feedback for Windows 10 IoT Core on Feedback Hub App (4/1/2017-1/23/2018)

  5. 吴恩达机器学习笔记40-用调和平均数F来进行查准率和查全率之间的权衡(Trading Off Precision and Recall by F sore)

    在很多应用中,我们希望能够保证查准率和查全率的相对平衡. 我们可以将不同阀值情况下,查全率与查准率的关系绘制成图表,曲线的形状根据数据的不同而不同: 我们希望有一个帮助我们选择这个阀值的方法.一种方法 ...

  6. cryptoJS AES 加解密简单使用

    简单记录一下,前端利用 cryptoJS 如何加解密的.主要是关于 AES 加解密. 需求描述:需要对 url 中的参数进行 AES 解密,然后再把该参数进行 MD5 加密通过接口传递. AES AE ...

  7. RISC-V指令集介绍 - 整数基本指令集

    1. 寄存器 32个x寄存器,RV32下x reg是32位宽 x0:硬连线 常数0 专门的零寄存器 x1-x31:31个通用reg 返回地址:没有强制要求那一个x作为lr,但是一般用x1 pc:额外的 ...

  8. Python - 使用Pylint检查分析代码

    1-简介 Home Page : https://www.pylint.org/ 检查语法错误,是否遵守编码风格标准.潜在的问题等: 支持自定义配置:例如显示或隐藏特定的警告,并且可以通过编写插件来添 ...

  9. 一文搞懂 Linux network namespace

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 本文通过 IP ...

  10. 工作随笔—Elasticsearch大量数据提交优化

    问题:当有大量数据提交到Elasticsearch时,怎么优化处理效率? 回答: 批量提交 当有大量数据提交的时候,建议采用批量提交. 比如在做 ELK 过程中 ,Logstash indexer 提 ...