在创建新实体时尝试引用现有实体时出错

时间:2013-09-23 18:33:12

标签: entity-framework ef-code-first entity-framework-5

我有一个实体“问题”,由两个实体“QuestionSet”和“Survey”使用。逻辑是,创建一组问题,但在向调查添加问题时,创建一个克隆,以便在问题集中编辑问题不会改变调查中的问题。 但是,由于有明确的更新功能,克隆(在调查中)需要知道它的来源(问题集中的问题)。

我通过添加

解决了这个问题
public virtual Question CreatedFrom { get; set; }

问题。但是,当我现在在我的控制器中执行以下操作时

oldQ = _questionRepository.GetById(qTransfer.Id);
q = new Question(oldQ);
q.CreatedFrom = oldQ;
q.Id = 0;

其中Q的复制构造函数生成问题值的完整副本(创建克隆)。

最后在我的回购中

if (item.Id == 0)
{
    Add(item); //this calls Add on dbset
}
ActiveContext.SaveChanges();

我收到此错误:IEntityChangeTracker的多个实例无法引用实体对象。

如果我发表评论q.CreatedFrom = oldQ;然后我不再收到错误。

我想要的只是在创建克隆时引用父级问题。我仍然希望原始问题能够独立运作。 我当然可以简单地用CreatedFromId替换CreatedFrom,但我认为直接引用会很好。

更新

这是我的克隆代码。克隆时我会复制CreatedFrom的引用,但是在克隆的对象中应该为null。

    public Question(Question q)
    {
        Id = q.Id;
        Description = q.Description;
        CreatedFrom = q.CreatedFrom;
        Type = q.Type;
        AddedTime = q.AddedTime;
        DeletedTime = q.DeletedTime;
        SortIndex = q.SortIndex;
        IsPageBreak = q.IsPageBreak;

        List<QuestionAlternative> list = new List<QuestionAlternative>();
        QuestionAlternative alternative;
        foreach (var alt in q.Alternatives)
        {
            alternative = new QuestionAlternative(alt);
            alternative.Id = 0;
            list.Add(alternative);
        }
        Alternatives = list;
    }

QuestionAlternative依次有一个拷贝构造函数:

    public QuestionAlternative(QuestionAlternative qa)
    {
        Id = qa.Id;
        Text = qa.Text;
        HasTextAnswer = qa.HasTextAnswer;
    }

1 个答案:

答案 0 :(得分:2)

我认为你的问题在这里:

  

“克隆时我会复制CreatedFrom的引用,但是应该这样做   在被克隆的对象中为null“

oldQ.CreatedFrom引用的值在调用构造函数时可能为null,但它仍然是引用类型。因此,当您致电q.CreatedFrom = oldQ时,oldQ.CreatedFrom也会设置为相同的引用 - 即它将引用自身。

如果您将CreatedFromID作为属性添加到问题上并使用它,那么我认为实体框架将为您修复您的引用。所以属性应该如下所示:

public int? CreatedFromID { get; set; }

[ForeignKey("CreatedFromID ")]
public virtual Question CreatedFrom { get; set; }

在你的构造函数中:

public Question(Question q)
{
   //Stop setting the reference property
   //CreatedFrom = q.CreatedFrom;

   //Set the foreign key instead        
   CreatedFromID = q.CreatedFromID;

   //EDIT - as discussed in the comments it would make more sense like:
   //CreatedFromID = q.ID;

}

值得一读Save the Grief and Use That Foreign Key

修改

您不必添加外键来解决此问题。如果你首先设置对逻辑正确的引用,那么它也应该修复它。

public Question(Question q)
{
    Id = 0;
    CreatedFrom = q;
}