我正在使用EF 6.0和代码优先方法。
我有通过Entity Framework在db中创建和更新数据的问题。我不确定在存储学生之前是否需要制作db.Groups.Attach(student.Group)
。保存学生后没有这个,我也有新的组,其名称与其他GroupId相同。
此外,我无法更新学生,因为我得到例外:The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
public class Student {
[Key]
public int StudentId {get; set;}
public string Name {get; set;}
public Group Group {get; set;}
}
public class Group {
[Key]
public int GroupId{ get; set;}
public string Name {get; set;}
public virtual ICollection<Student> Students {get; set;}
}
public class StudentDao {
public void createStudent(Student student) {
using (var db = new StorageContext()) {
// without this also creates new Group.
db.Groups.Attach(student.Group);
db.Students.Add(student);
db.SaveChanges();
}
}
public void updateStudent(Student student) {
using (var db = new StorageContext()) {
var original = db.Students.Find(student.StudentId);
if (original != null) {
original.Name = student.Name;
original.Group = student.Group;
db.SaveChanges(); //exception
}
}
}
}
答案 0 :(得分:2)
保存学生后没有这个( db.Groups.Attach(student.Group))我也有新的小组
这是因为{{1}将实体标记为Add
标记所有附加实体,这些实体尚未被上下文跟踪为已添加。这是一个EF功能,无论喜欢与否,所以你必须先附加你不想重新插入的实体。
此外,我无法更新学生,因为我得到了例外
出于某种原因,在更新方法中,学生及其组仍然附加到上下文。显然,DbSet
类中还有一些其他上下文活动。当您更新学生时,您必须确保此上下文的生命周期结束,否则(第二好)将学生和小组从中分离出来。
一个偏离主题的建议:如果可以的话,放弃这个DAO模式。当您在处理一个工作单元的类似服务的方法中使用StudentDao
及其DbContext
时,EF的效果会更好。使用这些DAO,它不可能在事务上工作,并且它们会导致大量重复的代码。
答案 1 :(得分:-1)
自从我在Entity上工作了一段时间但是从我记得你不能只改变组,你必须给它一个GroupID字段,改为那个,然后从数据库重新加载/更新Student对象这样就可以在同一个上下文中加载和分配Group对象。
这只是我使用NHibernate的原因之一。