zoukankan      html  css  js  c++  java
  • EF--EntityState相互转换

    • EF对数据做什么样的操作,是根据EF的上下文实体状态决定,实体状态有以下5种状态,下面我们就分别看下这5种状态

      数据准备,我们看到学生表里有20000名学生记录,最后1位学生的学生编号为0000020000


    1、Detached--实体跟上下文压根没关系

    我们看到我新创建了名学生,学号为0000020001,他是第20001位学生,此时打印上下文实体状态,实体和上下文是分离状态,没有任何关系,Detached是表示连内存跟踪都没有建立,跟上下文dbContext没有任何关系

    Student newStudent = new Student()
    {
      Student_ID = "0000020001",
      Student_Name = "猪猪打屁股",
      Student_Sex = "",
      Student_Identity_Card = "610102198307122319",
      Student_Birthday = DateTime.Now,
      Student_Email = "menglin2010@126.com",
      Student_Class = "741903613@qq.com",
      Create_Time = DateTime.Now
    };
    //1、Detached--实体跟context压根没关系
    {
      using (SchoolDBEntities dbContext = new SchoolDBEntities())
      {
        Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//实体跟context没关系 Detached
        newStudent.Student_Name = "小鱼儿";
        Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Detached
        dbContext.SaveChanges();//Detached啥事儿不发生
      }
    }

    2、Added--添加

    我们看到刚开始,newStudent这个学生和上下文是Detached分离状态,当把newStudent添加到上下文的Students集合里后,再打印newStudent的状态,newStudent就是Added状态了,当执行dbContext.SaveChange()后,把这个学生添加到表里,最后打印newStudent的状态,发现是Unchanged状态,Unchanged的意思是上下文和newStudent建立了跟踪,但是newStudent没有发生改变

    //2、Added--添加
    {
      using (SchoolDBEntities dbContext = new SchoolDBEntities())
      {
        Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Detached
        dbContext.Students.Add(newStudent);//插入数据(自增主键在插入成功后,会自动赋值过去)
        Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Added
        dbContext.SaveChanges();
        Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Unchanged(跟踪,但是没变化)
      }
    }

    3、Unchanged--跟踪,但是没变化

    Unchanged就是上下文和实体建立了跟踪,但是实体的值没有发生改变

    4、Modified--内存Clone

    把上次添加的那个猪猪打屁股的学生查出来,打印实体状态是Unchanged表示上下文建立了跟踪,但是实体未改变,然后修改学生姓名为“猪大头印实体状态是Modified,表示实体已发生了修改,当执行dbContext.SaveChange()后,把对这个学生的修改保存到表里,最后再打印newStudent的状态,发现是Unchanged状态,表示上下文和实体建立了跟踪,但是实体的值没有发生改变

     {
      using (SchoolDBEntities dbContext = new SchoolDBEntities())
      {
        Student currentStudent = dbContext.Students.Find("0000020001");//即时查询
        Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Unchanged(跟踪,但是没变化)
        currentStudent.Student_Name = "猪大头";//修改--内存clone 
        Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Modified
        dbContext.SaveChanges();//更新数据库,因为状态是Modified
       Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Unchanged(跟踪,但是没变化)
      }
    }

     5、Deleted--删除

    把上次修改的那个“猪大头”的学生查出来,打印其实体状态是Unchanged表示上下文建立了跟踪,但是实体未改变,然后从上下文的Students集合中移除,再打印实体状态是Deleted,表示实体已删除,当执行dbContext.SaveChange()后,把这个学生从表里删除掉,最后再打印newStudent的状态,发现是Detached状态,表示上下文和实体已经分离,和上下文没有任何关系了

    {
      using (SchoolDBEntities dbContext = new SchoolDBEntities())
      {
        Student currentStudent = dbContext.Students.Find("0000020001");//即时查询
        Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Unchanged(跟踪,但是没变化)
        dbContext.Students.Remove(currentStudent);
        Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Deleted
        dbContext.SaveChanges();//删除数据,因为状态是Deleted
        Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Detached已经从内存移除了
      }
    }

    •  实体和上下文建立跟踪的两种方式

    1、主动查询方式
    我们看到通过主键学号为“0000020000”查询出的这个学生实体和上下文建立了跟踪,只不过学生实体值没有发生任何改变,所以实体的状态是Unchanged

    {
      using (SchoolDBEntities dbContext = new SchoolDBEntities())
      {
           //1、查询方式
        Student currentStudent = dbContext.Students.Find("0000020000");
        Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);
      }
    }

    2、Attach附加方式

    修改前学号为0000020000的这名学生叫“石兴江”,性别为“女”,new Student()1个学生只不过这个学生的学号是在Student表里存在的“0000020000”,打印oldStudent实体状态是Detached,跟dbContext压根没关系,然后把oldStudent附加到上下文中,再打印oldStudent实体状态是Unchanged(这里说明下:oldStudent的Student_Identity_Card,Student_Birthday,Student_Email等属性是null,难道oldStudent实体状态不应该是Modified吗?难道不是把Student_Identity_Card,Student_Birthday,Student_Email改为null值吗?这里状态还是Unchanged,说明了属性值为null在EF里不是改为null,而是不做更改,最后一张图证明了这点Student_Identity_Card,Student_Birthday,Student_Email等属性在表里没有被改为null值),然后修改学号为0000020000的这名学生名称为“石兴江_Att”,性别为“男”,再打印oldStudent实体状态是Modified(因为实体发生了变化),dbContext.SaveChanges();执行后,我们发现0000020000的这名学生名字被改为了“石兴江_Att”,性别被改为了“男”,而Student_Identity_Card,Student_Birthday,Student_Email等字段值并没有被改为null

    {
      using (SchoolDBEntities dbContext = new SchoolDBEntities())
      {
        Student oldStudent = new Student()
        {
          Student_ID = "0000020000"
        };
    
        Console.WriteLine(dbContext.Entry<Student>(oldStudent).State);//Detached--实体跟dbContext压根没关系
        dbContext.Students.Attach(oldStudent);
        Console.WriteLine(dbContext.Entry<Student>(oldStudent).State);//Unchanged(跟踪,但是没变化)
        oldStudent.Student_Name = "石兴江_Att";
        oldStudent.Student_Sex = "";
        Console.WriteLine(dbContext.Entry<Student>(oldStudent).State);//Modified(因为实体发生了变化)
        dbContext.SaveChanges();
      }
    }

     

    •  按需更新,只更新指定的字段

    修改前,学号为“0000000001”的学生名字叫“赵峰真”,身份证号码为"1234567890",我们先查询出学号为“0000000001”的这名学生,打印实体状态为Unchanged,表示实体建立了跟踪但是实体未改变,然后修改学生姓名为“赵峰真001”,修改学生身份证号码为“abc”,再打印实体状态为Modified(因为实体发生了变化),然后指定这个学生的Student_Name属性为已修改,指定Student_Identity_Card属性为未被更改过(实际上我们本身是改了Student_Identity_Card的值为abc),最后dbContext.SaveChanges();后,我们发现只有学生姓名变成了“赵峰真001”  ,而学生身份号码并没有被更改为abc“”

    //按需更新--只修改指定的字段
    {
      using (SchoolDBEntities dbContext = new SchoolDBEntities())
      {
        Student student = dbContext.Students.Find("0000000001");//即时查询
        Console.WriteLine(dbContext.Entry<Student>(student).State);
        student.Student_Name = "赵峰真001";
        student.Student_Identity_Card = "abc";
        Console.WriteLine(dbContext.Entry<Student>(student).State);
        dbContext.Entry<Student>(student).Property("Student_Name").IsModified = true;//指定字段被改过
        dbContext.Entry<Student>(student).Property("Student_Identity_Card").IsModified = false;//指定字段未被改过
        Console.WriteLine(dbContext.Entry<Student>(student).State);
        dbContext.SaveChanges();                    
      }
    }

  • 相关阅读:
    JTAG的SWD接线方式
    Qt のEXecl
    人脸识别
    Qt实现基本QMainWindow主窗口程序
    Qt学习之路MainWindow学习过程中的知识点
    QT_FORWARD_DECLARE_CLASS
    标准的并发控制实现
    C++ DFS
    C# 互操作(一) 编写一个C++ COM组件
    Socket使用SOAP调用WCF
  • 原文地址:https://www.cnblogs.com/menglin2010/p/12240027.html
Copyright © 2011-2022 走看看