zoukankan      html  css  js  c++  java
  • Entity Framework入门教程(9)---离线场景附加实体图集到上下文

    附加离线实体图集到上下文

    这节主要内容是通过不同的方法将离线实体附加到上下文中。

    在离线场景中,保存一个实体要略微困难一些。当我们保存一个离线的实体图集或一个单独的离线实体时,我们需要做两件事。首先,我们要把实体附加到新的上下文中,让上下文了知道存在这些实体。其次,我们需要手动设置每个实体的EntityState,因为新的上下文不知道这些离线实体都经过了些什么操作,所以新的上下文不能自动地给实体添加EntityState。

    下图说明了此过程。

    为了将离线实体附加到上下文,并为实体图中的每个实体设置EntityState,EF提供下边几种方法:

    1.DbContext.Entry(entity).State=EntityState.Added/Modified/Deleted

    DbContext.Entry()方法返回一个指向特定实体的DbEntityEntry对象,这个DbEntityEntry对象提供有关实体实例的各种信息,我们也可以使用DbEntityEntry对象来操作实体。最重要的是,我们可以通过DbEntityEntry对象的state属性来指定实体的EntityState如下所示:
     context.Entry(entity).state = EntityState.Added/Modified/Deleted 
    一个栗子:

    var student = new Student() { //Root entity (无主键值)
        StudentName = "Bill",
        StandardId = 1,
        Standard = new Standard() //Child entity (有主键值)
            {
            StandardId = 1,
            StandardName = "Grade 1"
          },
     Courses = new List<Course>() {
      new Course(){ CourseName = "Machine Language" }, //Child entity (无主键值)
      new Course(){ CourseId = 2 } //Child entity (有主键值)
      }
     };
    
    using (var context = new SchoolDBEntities())
    {
      context.Entry(student).State = EntityState.Added;
      
        //context.ChangeTracker.Entities返回context追踪的所有EntityEntry实例
      foreach (var entity in context.ChangeTracker.Entries()){
        Console.WriteLine("{0}: {1}", entity.Entity.GetType().Name, entity.State);
      } 
    }
    
    //-----输出:
    Student: Added 
    Standard: Added
    Course: Added
    Course: Added    

    在上边的栗子中,Student实体图集包含了Standard和Course实体, context.Entry(student).State = EntityState.Added;  将父实体和子实体(无论有没有主键值)的EntityState都设置成Added,所以我们要谨慎使用Entry()方法。
    下表说明Entry()方法的规则

    父实体子实体
    Added Added
    Modified Unchanged
    Deleted All child entities will be null

    2.DbSet.Add()

    DbSet.Add()方法将整个实体图集附加到上下文中,同时把父实体和子实体的状态都设置成Added
    一个栗子:

    //离线实体图集
    Student disconnectedStudent = new Student() { StudentName = "New Student" };
    disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address", City = "City1" };
    
    using (var context = new SchoolDBEntities())
    {
        context.Students.Add(disconnectedStudent);
    
        // 获取EntityEntry实例用于查看实体的状态
        var studentEntry = context.Entry(disconnectedStudent);
        var addressEntry = context.Entry(disconnectedStudent.StudentAddress);
    
        Console.WriteLine("Student: {0}", studentEntry.State);
        Console.WriteLine("StudentAddress: {0}", addressEntry.State);
    }
    //输出
    Student: Added 
    StudentAddress: Added

    Dbset.Add()方法附加整个实体图集到上下文中,所有实体的状态都是Added,执行SaveChange()方法时会执行Insert操作,在数据库添加新记录

    3.DbSet.Attach()

    DbSet.Attach()方法将实体图集附加到一个新的上下文中,每个实体的状态都是Unchanged.
    一个栗子:

    //离线实体图集
    Student disconnectedStudent = new Student() { StudentName = "New Student" };
    disconnectedStudent.StudentAddress = new StudentAddress() { Address1 = "Address", City = "City1" };
    
    using (var context = new SchoolDBEntities())
    {
        context.Students.Attach(disconnectedStudent);
    
        // 获取EntityEntry实例用于查看实体的状态
        var studentEntry = context.Entry(disconnectedStudent);
        var addressEntry = context.Entry(disconnectedStudent.StudentAddress);
    
        Console.WriteLine("Student: {0}",studentEntry.State);
        Console.WriteLine("StudentAddress: {0}",addressEntry.State);
    }
    //----输出
    Student: Unchanged 
    StudentAddress: Unchanged

    EF系列目录链接:Entity Franmework系列教程汇总

  • 相关阅读:
    [Z] Windows 8/10 audio编程
    [Z]The Boost C++ Libraries
    [Z] windows进程在32、64位系统里用户和系统空间的地址范围
    [Z] 关于c++ typename的另一种用法
    [z] 人工智能和图形学、图像处理方面的各种会议的评级
    [Z] 计算机类会议期刊根据引用数排名
    关于windows的service编程
    关于Linux session管理与GUI架构
    搭建框架-ECS.ECommerce
    不调用构造函数而创建一个类型实例
  • 原文地址:https://www.cnblogs.com/wyy1234/p/9635358.html
Copyright © 2011-2022 走看看