实体框架实体状态管理混乱

本文关键字:实体 混乱 管理 状态 框架 | 更新日期: 2023-09-27 18:26:52

我已经使用EF(现在是6.1.1)一段时间了。但每次我需要在控制器中使用多个实体(使用MVC)时,我都会迷失自我。

国家对实体的管理给我带来了巨大的困惑,当我认为我理解这种操作时,又来了一个惊喜。

例如(我目前的困惑):

我有以下课程:

public class A
{
    public int Id { get; set; }
    public C c { get; set; }
}
public class B
{
    public int Id { get; set; }
    public C c { get; set; }
}
public class C
{
    public int Id { get; set; }
    public string anotherProperty { get; set; }
}

我有一个控制器:

[HttpPost]
public void CopyEntityAction(A a){
    var b = new B() {
        c = a.c // <== here is the problem
    };
    db.Bs.Add(b);
}

我想做的是将C从A复制(创建另一个实体)到B,而不是链接到同一个C.Id

我怎样才能做到这一点?

感谢您抽出时间

*我认为EF可以自动处理

编辑1

我也试过这个:

[HttpPost]
public void CopyEntityAction(A a){
    var b = new B();
    var c2 = a.c;
    db.Entry(c2).State = EntityState.Added;
    b.c = c2;
    db.Bs.Add(b);
    db.SaveChanges();
}

实体框架实体状态管理混乱

我想你需要这样的东西。否则,您将处理完全相同的C对象,而不是创建一个新对象。

var b = new B() {
        c = new C { Id = a.c.Id, anotherProperty = a.c.Anotherproperty } // <== here is the problem
    };

您可能还需要明确地将新的C添加到上下文的C集合中。

这真的没有那么令人困惑。归根结底就是数据的来源。当您从实体框架中检索对象时,它会"附加"到您的上下文中。但是,当您数据发布到一个操作,并让modelbinder用该数据新建实体的实例(通过将其作为参数包含)时,它是而不是附加的。这意味着实体框架对这个对象一无所知。它不知道它来自哪里,以前是否保存过(这是更新还是插入?)等等。所以,你有责任告诉它在这一点上该怎么做。这就是EntityState枚举的作用。