【问题标题】:Entity Framework: Create and update related objects in WPF实体框架:在 WPF 中创建和更新相关对象
【发布时间】:2013-11-29 02:31:10
【问题描述】:

我正在使用 EF 6.0 和代码优先方法。 我在通过实体框架在 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
            }
        }
    }
}

【问题讨论】:

    标签: c# wpf entity-framework


    【解决方案1】:

    没有这个 (db.Groups.Attach(student.Group)) 保存学生后我也有新组

    这是因为 Add 将实体添加到 DbSet 会将 所有 尚未被上下文跟踪的附着实体标记为已添加。无论喜欢与否,这是一个 EF 功能,因此您必须先附加不想重新插入的实体。

    此外,我无法更新学生,因为我遇到了异常

    由于某种原因,在更新方法中,学生及其组仍然附加到上下文。显然,StudentDao 类中还有其他一些活动的上下文。当您更新学生时,您必须确保此上下文的生命周期结束,否则(次优)将学生和组与其分离。

    离题建议:如果可以,请放弃这种 DAO 模式。当您在处理一个工作单元的类似服务的方法中使用DbContext 及其DbSets 时,EF 工作得更好。使用这些 DAO 就不可能以事务方式工作,并且会导致大量重复代码。

    【讨论】:

    • 感谢您的回复。 “在类似服务的方法中使用 DbContext 及其 DbSets”是什么意思?你的意思是在一个类中有一个 dbcontext 吗?能否详细说明参考一篇文章?
    【解决方案2】:

    自从我从事实体工作以来已经有一段时间了,但据我所知,你不能只更改组,你还必须给它一个 GroupID 字段,改为更改它,然后从数据库中重新加载/更新学生对象以便从同一上下文中加载和分配 Group 对象。

    这只是我使用 NHibernate 的原因之一。

    【讨论】:

    • 所以我需要更改 GroupId 而不是 Group?这意味着在课堂上学生我必须有 Group 和 GroupId?
    • 是的。至少我在过去从事的实体框架项目中看到它是这样设置的。
    猜你喜欢
    • 2012-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多