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

时间:2014-10-17 17:56:44

标签: c# asp.net-mvc entity-framework

我在相关时间使用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();
}

2 个答案:

答案 0 :(得分:0)

真的不是那么令人困惑。它归结为数据的来源。从Entity Framework检索对象时,它将“附加”到您的上下文中。但是,当您数据发布到某个操作并让modelbinder新建一个具有该数据的实体实例(通过将其作为参数包含在内)时,它附加。这意味着Entity Framework对此对象一无所知。它不知道它来自何处,是否曾经被保存过(这是更新还是插入?)等等。所以,你可以告诉它该做什么。这就是EntityState enum的用途。

答案 1 :(得分:0)

我认为你需要这样的东西。否则,您正在处理完全相同的C对象,而不是创建新对象。

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

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