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

来源:互联网 发布:域名未通过所有权验证 编辑:程序博客网 时间:2024/05/23 01:11

前言

此文章只是为了给新手程序员,和经验不多的程序员,在学习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);        }    }
复制代码

生成数据库:

image

数据库关系图:

image

基础工作建立完毕。

 

正文:

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

源代码下载

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 跑了步全身酸痛怎么办 运动后全身没力气怎么办 学完游泳不会换气怎么办 猫不吃饭精神不好怎么办 运动完头晕目眩想吐怎么办 酒后第二天恶心想吐怎么办 剧烈运动后肌肉酸痛怎么办 剧烈运动后吐了怎么办 长跑后头晕想吐怎么办 运动后一直想吐怎么办 跑多了恶心想吐怎么办 剧烈运动恶心想吐怎么办 长跑之后 恶心想吐怎么办 喝咖啡后绞心痛怎么办 牛奶喝多了胃胀怎么办 运动后大量出汗头晕怎么办 屁股出汗淹的特别痛怎么办 运动完感觉很累怎么办 跑步后感觉很累怎么办 输液多了伤脾胃怎么办 运动完后特别晕怎么办 运动过量大腿肌肉酸痛怎么办 13岁发烧38.2度怎么办 头晕恶心想吐四肢无力怎么办 烧退了浑身疼怎么办 下午睡久了头疼怎么办 一天睡久了头疼怎么办 在家躺久了头疼怎么办 4周多儿童睡眠差怎么办 6岁儿童睡眠差怎么办 四年级的孩子不会写作文怎么办 四年级的孩子写不出作文怎么办? 欠了三万网贷怎么办 打完篮球浑身疼怎么办 在部队当兵意外死亡了怎么办 派派没有体力瓶怎么办 e记账登录不上怎么办 洁净净化区湿度高怎么办 政府测量土地少算了面积怎么办 北京武警欠我钱怎么办 被小混混打了怎么办