在EF 6中保存未被跟踪的实体图
在前一章中,您学习了如何保存断开连接的单个实体。在这里,您将了解如何保存断开连接的实体图。
在断开连接的场景中更新实体图是一项复杂的任务,需要仔细考虑设计。
更新断开连接的实体图的问题在于上下文不知道在客户端对它执行了什么操作。如下图所示,新的上下文不知道每个实体的状态:
在调用SaveChages()方法之前,我们需要识别实体图中每个实体的状态。有不同的模式可以识别实体状态,我们在使用实体框架设计数据层时需要考虑这些模式。这里我们将使用key属性来标识实体状态。
Using Key Property
您可以使用每个实体的key (PrimaryKey)属性来确定其状态。如果key属性的值是CLR数据类型的默认值,则将其视为一个新实体。否则,将其视为一个现有实体。例如,如果一个键属性的数据类型是int,属性的值是0,那么它是一个新的实体,EF需要执行INSERT命令。如果一个值非零,那么它是一个现有的实体,EF需要执行UPDATE命令。
下面的例子演示了用相关的Standard和Course实体保存Student实体图:
var student = new Student() { //Root entity (empty key)
StudentName = "Bill",
Standard = new Standard() //Child entity (with key value)
{
StandardId = 1,
StandardName = "Grade 1"
},
Courses = new List<Course>() {
new Course(){ CourseName = "Machine Language" }, //Child entity (empty key)
new Course(){ CourseId = 2 } //Child entity (with key value)
}
};
using (var context = new SchoolDBEntities())
{
//基于StandardId标记标准
context.Entry(student).State = student.StudentId == 0 ? EntityState.Added : EntityState.Modified;
context.Entry(student.Standard).State = student.Standard.StandardId == 0 ? EntityState.Added : EntityState.Modified;
foreach (var course in student.Courses)
context.Entry(course).State = course.CourseId == 0 ? EntityState.Added : EntityState.Modified;
context.SaveChanges();
}
在上面的例子中,student实体图包括相关的Standard和Course实体。上下文根据键属性值为每个实体设置适当的状态。如果为零,则设置Added状态,否则设置Modified状态。SaveChanges()方法将为每个实体对数据库执行适当的INSERT或UPDATE命令。
参考
https://www.entityframeworktutorial.net/
https://msdn.microsoft.com/