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. CentOS 5 常见的configure error的解决方法

    仅限于CentOS 5 configure: error: No curses/termcap library found 网上有的说法是: --with-named-curses-libs=/usr ...

  2. 常用类:Object

    2017-08-08 Object :作为所有类的根类,(超类,父类) 常用的方法: public int hasCode(){//返回该对象的哈希码值(地址)}:判断对象是否在同一内存地址上 pub ...

  3. python之常用模块4

    pyinotify模块 pip3 install pyinotify pyinotify提供的事件: 事件标志 事件含义 IN_ACCESS 被监控项目或者被监控目录中的文件被访问,比如一个文件被读取 ...

  4. Python编程练习:使用 turtle 库完成六边形的绘制

    绘制效果: 源代码: # 六边形 import turtle turtle.setup(650, 350, 200, 200) turtle.penup() turtle.pendown() turt ...

  5. PHP安装BCMath扩展

    我们都知道,大多数编程语言对于浮点型数据格式遵循 IEEE 754 标准,PHP也不例外,这就会导致在使用浮点数运算的过程中会有精度丢失的问题.PHP提供了BCMath库来支持更加精确的计算.但是我的 ...

  6. 解决微信小程序的wx-charts插件tab切换时的显示会出现位置移动问题-tab切换时,图表显示错乱-实现滑动tab

    解决Echarts在微信小程序tab切换时的显示会出现位置移动问题 tab切换时,图表显示错乱 <canvas class="kcanvas" canvas-id=" ...

  7. 简单读!Mybatis源码(一)一条select的一生

    工具除了会用,还应该多做点.我觉得使用一个软件工具(开源类),一般会经历几个步骤: 1. 通过wiki了解大致作用,然后开始码代码: 2. 系统性地学习其特性,找出可能需要的点,用上去: 3. 通过阅 ...

  8. KNN算法基本实例

    KNN算法是机器学习领域中一个最基本的经典算法.它属于无监督学习领域的算法并且在模式识别,数据挖掘和特征提取领域有着广泛的应用. 给定一些预处理数据,通过一个属性把这些分类坐标分成不同的组.这就是KN ...

  9. 机器学习入门03 - 降低损失 (Reducing Loss)

    原文链接:https://developers.google.com/machine-learning/crash-course/reducing-loss/ 为了训练模型,需要一种可降低模型损失的好 ...

  10. .NET Core 如何调用 WebService

    0.使用背景 因为现在的项目都是基于 .NET Core 的,但是某些需要调用第三方的 WebService 服务,故有了此文章.其基本思路是通过微软提供的 Svcutil 工具生成代理类,然后通过 ...