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过程。

源代码下载

时间: 11-07

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

web day19 Service层处理事务(利用ThreadLocal),TxQueryRunner小工具,单表练习(增删改查操作),分页

Service事务 DAO中不是处理事务的地方,因为DAO中的每个方法都是对数据库的一次操作 在Service中不应该出现Connection,它应该只在DAO中出现, 因为它是JDBC的东西,JDBC的东西是用来连接数据库的 修改JdbcUtils 我们把对事务的开启和关闭放到JdbcUtils中,在Service中调用JdbcUtils的方法来完成事务的处理, 但在Service中就不会再出现Connection这一"禁忌"了. 代码 public class JdbcUtils

3.django模板,单表ORM增删改查

1.Django模板语法 模板语法: 变量: {{}} 1 深度查询 句点符 2 过滤器 {{val|filter_name:参数}} 标签: {% %} 1.1Django模板使用 from django.shortcuts import render import datetime def index(request): now = datetime.datetime.now() return render(request,"index.html",{"current_t

ORM 实现数据库表的增删改查

这次通过反射技术来实现一下数据库表的增删改查对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping) 注:引用时约束了以下几点: 数据库表的表名与类的类名一致 数据库字段名和类字段名一致 自增字段的访问权限为private其余字段都为public 注:如果用的是MySql数据库,有提供好的MySqlhelper非MySql数据库可以参考我写好的SqlHelper SqlHelper参考位置:http://www.cnblogs.c

Windows下安装MySQLdb, Python操作MySQL数据库的增删改查

这里的前提是windows上已经安装了MySQL数据库,且配置完毕,能正常建表能操作.在此基础上只需安装MySQL-python-1.2.4b4.win32-py2.7.exe就ok了,只有1M多.这个有点类似jdbc里的那个jar包. 下载链接:http://sourceforge.net/projects/mysql-python/ , 百度云盘 :http://pan.baidu.com/s/1dDgnfpR 密码:7bna 接着import MySQLdb就能使用了,下面给出测试代码:

【框架】[Hibernate]利用Hibernate进行单表的增删改查-Web实例

转载请注明出处:http://blog.csdn.net/qq_26525215 本文源自[大学之旅_谙忆的博客] 前面两篇博客已经将Hibernate的基础知识讲解得差不多了,差不多到写实例的时候了. 本篇只用hibernate进行单表的增删改查. 应用Hibernate,对students表进行增删改查. service层和DAO层,我都是直接写实现类了(因为这里主要是演示一下Hibernate的使用),如果是开发项目,注意一定要写接口! 准备数据库: 首先准备一个students表: cr

MySQL数据库之表的增删改查

目录 MySQL数据库之表的增删改查 1 引言 2 创建表 3 删除表 4 修改表 5 查看表 6 复制表 MySQL数据库之表的增删改查 1 引言 1.MySQL数据库中,数据库database就是硬盘上的一个文件夹,表table就是文件夹里面的一个文件 2.表中的一条记录就相当于文件中的一行内容,与excel表类似,表table中有不同的标题,称之为字段 3.本节对表结构做增删改查,即创建表.删除表.修改表.查看表结构,至于表中数据的增删改查日后单独总结 2 创建表 1.创建一张表,需要建一

spool命令、创建一个表,创建并且copy表,查看别的用户下的表,rowid行地址 索引的时候使用,表的增删改查,删除表,oracle的回收站

  1.spool命令 spool "D:\test.txt" spool off SQL> host cls 2.创建一个表 SQL> --条件(1):有创建表的权限,(2):有表空间 SQL> desc t4; 名称                                      是否为空? 类型 ----------------------------------------- -------- ------------------------

AngularJS中使用$http对MongoLab数据表进行增删改查

本篇体验使用AngularJS中的$http对MongoLab数据表进行增删改查. 主页面: <button ng-click="loadCourse()">Load Course</button> <button ng-click="toggleAddCourse(true)">Add New Course</button> <ng-includce src="'course_list.html'&q

数据库和表的增删改查(新手向)

数据库的增删改查: 使用的是mysql数据库,完成数据库的创建,删除,修改,查询: 登录界面 1.数据库的创建,create database db_name;          回车,此时我们创建了一个名为db_name的数据库,这时候注意,当你没有定义数据库的编码字符集的时候,系统默认是latin1的编码格式.练习:创造一个名为"emp"的数据库: 已经完成数据库emp的建立(由于没有定义数据库的编码字符集,所以默认为latin1). 2.数据库的修改,alter database