2013-09-23 4 views
0

У меня есть объект «Вопрос», который используются обеими объектами «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, но я подумал, что было бы неплохо с прямой ссылкой.

Update

Вот мой Клонирование код. При клонировании я копирую ссылку для CreateFrom, но это должно быть 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

Можете ли вы показать код клонирования внутри своего конструктора копирования? – Colin

+0

К счастью, я обновил вопрос –

ответ

2

Я думаю, ваша проблема здесь:

"While cloning I copy the reference for CreatedFrom however that should be null in the object being cloned"

Значение, которое oldQ.CreatedFrom ссылки может быть пустым в точке что конструктор вызывается, но он по-прежнему является ссылочным типом. Поэтому, когда вы вызываете q.CreatedFrom = oldQ, тогда oldQ.CreatedFrom также устанавливается в ту же ссылку, то есть будет ссылаться на себя.

Если вы добавили CreatedFromID в качестве свойства в вопрос и используете его вместо этого, я думаю, что 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

EDIT

Вы не должны добавьте внешний ключ для решения этой проблемы. Если вы сначала установите ссылки на логически правильную вещь, это также должно исправить.

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

Я пытаюсь ваше решение, но когда я запускаю обновление миграции, я получаю эту «Последовательность не содержит элементов» в Add-Migration. –

+0

Звучит как проблема в методе Seed для меня – Colin

+0

Это будет, но мое семя пуст. Это описывает мою проблему, но я не переименовал идентификатор, поэтому не имеет смысла: http://entityframework.codeplex.com/workitem/ 569 –

Смежные вопросы