EF--EntityState相互轉換

  • EF對數據作什麼樣的操做,是根據EF的上下文實體狀態決定,實體狀態有如下5種狀態,下面咱們就分別看下這5種狀態

  數據準備,咱們看到學生表裏有20000名學生記錄,最後1位學生的學生編號爲0000020000數據庫


一、Detached--實體跟上下文壓根不要緊spa

咱們看到我新建立了名學生,學號爲0000020001,他是第20001位學生,此時打印上下文實體狀態,實體和上下文是分離狀態,沒有任何關係,Detached是表示連內存跟蹤都沒有創建,跟上下文dbContext沒有任何關係3d

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
};
//一、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啥事兒不發生
  }
}

二、Added--添加code

咱們看到剛開始,newStudent這個學生和上下文是Detached分離狀態,當把newStudent添加到上下文的Students集合裏後,再打印newStudent的狀態,newStudent就是Added狀態了,當執行dbContext.SaveChange()後,把這個學生添加到表裏,最後打印newStudent的狀態,發現是Unchanged狀態,Unchanged的意思是上下文和newStudent創建了跟蹤,可是newStudent沒有發生改變blog

//二、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(跟蹤,可是沒變化)
  }
}

三、Unchanged--跟蹤,可是沒變化內存

Unchanged就是上下文和實體創建了跟蹤,可是實體的值沒有發生改變it

四、Modified--內存Cloneclass

把上次添加的那個豬豬打屁股的學生查出來,打印實體狀態是Unchanged表示上下文創建了跟蹤,可是實體未改變,而後修改學生姓名爲「豬大頭印實體狀態是Modified,表示實體已發生了修改,當執行dbContext.SaveChange()後,把對這個學生的修改保存到表裏,最後再打印newStudent的狀態,發現是Unchanged狀態,表示上下文和實體創建了跟蹤,可是實體的值沒有發生改變im

 {
  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(跟蹤,可是沒變化)
  }
}

 五、Deleted--刪除d3

把上次修改的那個「豬大頭」的學生查出來,打印其實體狀態是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已經從內存移除了
  }
}

  •  實體和上下文創建跟蹤的兩種方式

一、查詢方式
咱們看到經過主鍵學號爲「0000020000」查詢出的這個學生實體和上下文創建了跟蹤,只不過學生實體值沒有發生任何改變,因此實體的狀態是Unchanged

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

 

二、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屬性爲未被更改過,最後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();                    
  }
}

相關文章
相關標籤/搜索