EF Codefirst 中间表(关系表)的增删改查(转)
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表达对其进行增删改查的多种情况
创建一个订单
添加订单信息、员工信息到数据表中,建立两则多对多的联系
清空中间表之间的数据,而不影响employee和order表中的数据
给中间表添加数据,给两个已经存在的数据建立中间关系
操作中间表,修改两个表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 中间表(关系表)的增删改查(转)的更多相关文章
- 一、数据库表中字段的增删改查,二、路由基础.三、有名无名分组.四、多app共存的路由分配.五、多app共存时模板冲突问题.六、创建app流程.七、路由分发.八、路由别名,九、名称空间.十、反向解析.十一、2.x新特性.十二、自定义转换器
一.数据库表中字段的增删改查 ''' 直接在modules中对字段进行增删改查 然后在tools下点击Run manage.py Task执行makemigrations和migrate 注意在执行字 ...
- Django项目的创建与介绍.应用的创建与介绍.启动项目.pycharm创建启动项目.生命周期.三件套.静态文件.请求及数据.配置Mysql完成数据迁移.单表ORM记录的增删改查
一.Django项目的创建与介绍 ''' 安装Django #在cmd中输入pip3 #出现这个错误Fatal error in launcher: Unable to create process ...
- 第三百零七节,Django框架,models.py模块,数据库操作——表类容的增删改查
Django框架,models.py模块,数据库操作——表类容的增删改查 增加数据 create()方法,增加数据 save()方法,写入数据 第一种方式 表类名称(字段=值) 需要save()方法, ...
- 五 Django框架,models.py模块,数据库操作——表类容的增删改查
Django框架,models.py模块,数据库操作——表类容的增删改查 增加数据 create()方法,增加数据 save()方法,写入数据 第一种方式 表类名称(字段=值) 需要save()方法, ...
- mysql对库,表及记录的增删改查
破解密码 #1.关闭mysqlnet stop mysqlmysql还在运行时需要输入命令关闭,也可以手动去服务关闭 #2.重新启动mysqld --skip-grant-tables跳过权限 #3m ...
- Oracle学习总结_day01_day02_表的创建_增删改查_约束
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 更新: SELECT * FROM (SELECT R ...
- Java代码自动生成,生成前端vue+后端controller、service、dao代码,根据表名自动生成增删改查功能
本项目地址:https://github.com/OceanBBBBbb/ocean-code-generator 项目简介 ocean-code-generator采用(适用): ,并使用m ...
- 表结构修改以及sql增删改查
修改表结构 修改表名 alter table 表名 rename 新名 增加字段 alter table 表名 add 字段名 数据类型 约束 删除字段 alter table 表名 drop 字段名 ...
- 如何搭建一个WEB服务器项目(二)—— 对数据库表进行基本的增删改查操作
使用HibernateTemplate进行增删改查操作 观前提示:本系列文章有关服务器以及后端程序这些概念,我写的全是自己的理解,并不一定正确,希望不要误人子弟.欢迎各位大佬来评论区提出问题或者是指出 ...
- hibernate课程 初探单表映射3-5 hibernate增删改查
本节简介: 1 增删改查写法 2 查询load和查询get方法的区别 3 demo 1 增删改查写法 增加 session.save() 修改 session.update() 删除 session. ...
随机推荐
- FPGA计算中定标与位扩展的实现
我不知道名字取对没有,在FPGA计算中有时往往需要在不溢出的情况下将数扩大,从而获得更好的计算精度. 比如.在一个8位宽的系统中,将x=0000_0010,算术左移m=5位之后得到xt=0100_00 ...
- Ftp主动模式和被动模式以及java连接ftp模式设置
Ftp主动模式和被动模式以及java连接ftp模式设置 https://www.cnblogs.com/huhaoshida/p/5412615.html (1) PORT(主动模式) PORT中文称 ...
- 升讯威微信营销系统开发实践:(2)中控服务器的详细设计( 完整开源于 Github)
GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...
- My Feedback for Windows 10 IoT Core on Feedback Hub App (4/1/2017-1/23/2018)
- 吴恩达机器学习笔记40-用调和平均数F来进行查准率和查全率之间的权衡(Trading Off Precision and Recall by F sore)
在很多应用中,我们希望能够保证查准率和查全率的相对平衡. 我们可以将不同阀值情况下,查全率与查准率的关系绘制成图表,曲线的形状根据数据的不同而不同: 我们希望有一个帮助我们选择这个阀值的方法.一种方法 ...
- cryptoJS AES 加解密简单使用
简单记录一下,前端利用 cryptoJS 如何加解密的.主要是关于 AES 加解密. 需求描述:需要对 url 中的参数进行 AES 解密,然后再把该参数进行 MD5 加密通过接口传递. AES AE ...
- RISC-V指令集介绍 - 整数基本指令集
1. 寄存器 32个x寄存器,RV32下x reg是32位宽 x0:硬连线 常数0 专门的零寄存器 x1-x31:31个通用reg 返回地址:没有强制要求那一个x作为lr,但是一般用x1 pc:额外的 ...
- Python - 使用Pylint检查分析代码
1-简介 Home Page : https://www.pylint.org/ 检查语法错误,是否遵守编码风格标准.潜在的问题等: 支持自定义配置:例如显示或隐藏特定的警告,并且可以通过编写插件来添 ...
- 一文搞懂 Linux network namespace
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 本文通过 IP ...
- 工作随笔—Elasticsearch大量数据提交优化
问题:当有大量数据提交到Elasticsearch时,怎么优化处理效率? 回答: 批量提交 当有大量数据提交的时候,建议采用批量提交. 比如在做 ELK 过程中 ,Logstash indexer 提 ...