我有一个实体“问题”,由两个实体“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;
}
答案 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;
}