EF Codefirst 中間表(關系表)的增刪改查(轉)


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);
        }
    }
復制代碼

生成數據庫:

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

源代碼下載



來源:https://www.cnblogs.com/wer-ltm/p/4944745.html


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com