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;
this.Property(o => o.CustomerName).IsRequired().HasMaxLength();//订单名称为必填,最大长度为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(); //设置多对多的关系 .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 = ; i < ; 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 == );
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 == );
//设计订单表的集合,将新增的数据填充进来
int[] orderIdList = {, , , , , , };
//判断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 == );
//需要更改对应的OrderId列表
int[] orderIdList = {, , , , , , }; 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过程。
EF Codefirst 多对多关系 操作中间表的 增删改查(CRUD)的更多相关文章
- 国产化之路-统信UOS + Nginx + Asp.Net MVC + EF Core 3.1 + 达梦DM8实现简单增删改查操作
专题目录 国产化之路-统信UOS操作系统安装 国产化之路-国产操作系统安装.net core 3.1 sdk 国产化之路-安装WEB服务器 国产化之路-安装达梦DM8数据库 国产化之路-统信UOS + ...
- MyBatis-单表的增删改查(CRUD)操作
在学习MyBatis的单表的增删改查操作之前,还是再次熟悉下MyBatis这个框架,只有对其熟悉的情况下,才能很好的使用,灵活的开发. MyBatis优点: ...
- Hibernate5笔记2--单表的增删改查操作
单表的增删改查操作: (1)定义获取Session和SessionFactory的工具类: package com.tongji.utils; import org.hibernate.Session ...
- python全栈开发day61-django简单的出版社网站展示,添加,删除,编辑(单表的增删改查)
day61 django内容回顾: 1. 下载: pip install django==1.11.14 pip install -i 源 django==1.11.14 pycharm 2. 创建项 ...
- django模型层 关于单表的增删改查
关于ORM MTV或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库, 通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员 ...
- Mysql数据表的增删改查
---恢复内容开始--- Mysql数据表的增删改查 1.创建表 语法:CREATE TABLE 表名(字段1,字段2,字段3.......) CREATE TABLE `users` ( `us ...
- ORM 实现数据库表的增删改查
这次通过反射技术来实现一下数据库表的增删改查对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping) 注:引用时约束了以下几点: 数据 ...
- day 57 data 插件 表的增删改查
一 data的含义 在匹配的元素集合中的所有元素上存储任意相关数据或返回匹配的元素集合中的第一个元素的给定名称的数据存储的值. 1 .data(key, value): 描述:在匹配 ...
- springLdap 操作ldap示例(增删改查)
转自:http://blog.csdn.net/sundenskyqq/article/details/9002440 这部分的示例网上的确有很多,但是个人在查找的过程中还是感到不够满意,所以就自己总 ...
随机推荐
- 【Hibernate框架】关联映射(多对多关联映射)
按着我们的总结行进计划,接下来,就是有关于多对多映射的总结了. 我们来举个例子啊,很长时间以来,房价暴涨不落,但是还有很多人拥有很多套房产,假如说,一个富豪拥有九套房产,家里人么准去住哪一套,我们就以 ...
- webform文件上传、图片水印、验证码
文件上传: 所用控件:FileUpload 使用时的思路: 1.判断用户是否选中了文件 FileUpload.FileName获取选中的文件名,判断长度,如果长度大于零就代表已经选择了文件 JS端:通 ...
- 域名解析与多域名绑定多个Tomcat项目
第一步.域名解析 1.登录阿里云的服务器地址:https://www.aliyun.com/ 新手礼包地址:https://s.click.taobao.com/as9o9Ox 2.点击控制台 3 ...
- 转:WaitForSingleObject()函数、WaitForMultipleObject()函数
http://blog.csdn.net/xiaobai1593/article/details/6672193 在多线程下面,有时候我们会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以 ...
- sql union和union all的用法及效率
UNION指令的目的是将两个SQL语句的结果合并起来.从这个角度来看, 我们会产生这样的感觉,UNION跟JOIN似乎有些许类似,因为这两个指令都可以由多个表格中撷取资料. UNION的一个限制是两个 ...
- Java|今天起,别再扯订阅和回调函数
编程史上有两个令人匪夷所思的说辞,一个是订阅,一个是回调函数. 我想应该还有很多同学为“事件的订阅”和“回调函数”所困扰,因为事情本来就不应该按这个套路来解释. 多直白,所谓的“回调函数”你完全可以线 ...
- HTML5 audio与video标签实现视频播放,音频播放
随着互联网的飞速发展以及HTML5的应用,越来越多的项目中用到video,audio当常用标签. <audio> 标签属性 <audio src="song.mp3&quo ...
- Markdown 语法总结
Markdown 语法总结 Markdown是一个神奇的语言,他比html简单,它巧妙地将内容和格式结合起来.很多平台支持Markdown语法编辑,比如github.博客园等. 下面总结一Markdo ...
- spring动态代理
接下来我们来体会下动态代理带给我们的便利 package aop006; public interface Girl { public void KFC(String datetime); publi ...
- JQuery对象与DOM对象的区别与转换
1.jQuery对象和DOM对象的区别 DOM对象,即是我们用传统的方法(javascript)获得的对象,jQuery对象即是用jQuery类库的选择器获得的对象; eg: var domObj ...