【问题标题】:Error when trying to reference existing entity when creating new创建新实体时尝试引用现有实体时出错
【发布时间】:2013-09-28 18:24:25
【问题描述】:

我有一个实体“Question”,供实体“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;然后我不再收到错误。

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

更新

这是我的克隆代码。克隆时,我复制了 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;
    }

【问题讨论】:

  • 你能在你的复制构造函数中显示克隆代码吗?
  • 很高兴,我更新了问题

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


【解决方案1】:

我认为你的问题在这里:

“在克隆时,我复制了 CreatedFrom 的引用,但这应该 在被克隆的对象中为 null"

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

如果您将 CreatedFromID 添加为 Question 的属性并改用它,那么我认为 Entity Framework 将为您修复您的引用。所以属性应该是这样的:

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;
}

【讨论】:

  • 我正在尝试您的解决方案,但是当我运行迁移更新时,我在 Add-Migration 上收到此“序列不包含任何元素”。
  • 在我看来你的 Seed 方法有问题
  • 会,但我的种子是空的。这描述了我的问题,但我没有重命名 ID,所以没有完全意义:entityframework.codeplex.com/workitem/569
  • 所以我把名字改成了 CreatedFromQuestion 和 CreatedFromQuestionId。我不再收到错误(不知道为什么),而且一切似乎都很好。我真的不喜欢将外键放在我的实体中,因为实体应该完全存储而不知道。但我的时间不多了,这行得通。
  • 其实这里的根本原因是你将 CreatedFrom 引用设置为错误的东西。它不是从旧问题的旧问题创建的。它是从旧问题创建的,它也不应该有旧问题的 id 吗?我将添加一些示例代码
猜你喜欢
  • 2023-03-26
  • 2017-05-13
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-05
  • 2018-04-30
相关资源
最近更新 更多