转载

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);  } } 

生成数据库:

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

数据库关系图:

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

基础工作建立完毕。

正文:

我们都知道在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过程。

源代码下载

正文到此结束
Loading...