ParentFoo и т. Д. Не связаны с вашим контекстом, поэтому контекст будет обрабатывать их как новые объекты.Избегайте передачи сущностей за пределы контекста, в который они загружены, чтобы избежать подобных проблем.Вместо этого, если вы загружаете родительские / дочерние данные, необходимые с идентификаторами, в модели представлений POCO, а затем извлекаете ссылки по мере необходимости, вы можете избежать проблем с несвязанными объектами.
Используя свой код:
void AddGrandparent(int id, ParentFoo pf)
{
using (var dc = dcHelper_.CreateDataContext())
{
var parent = dc.ParentFoos.Find(pf.Id);
dc.GrandparentFoos.Add(new GrandparentFoo
{
Id = id,
ParentFoo = parent
});
dc.SaveChanges();
}
}
Если GrandParentFoo имеет установленный идентификатор, вы можете отказаться от установки идентификаторов, EF будет игнорировать его при добавлении в контекст.Если parent содержит ссылку на grandparent, вам, возможно, потребуется установить эту ссылку и в ParentFoo.
var grandParent = dc.GrandparentFoos.Add(new GrandparentFoo
{
Id = id,
ParentFoo = parent
});
parent.GrandparentFoo = grandParent;
Edit: если у GrandParent есть коллекция Parent, и вы хотите создать Grandparent и связать его содин существующий родительский элемент:
Сначала убедитесь, что коллекция Parents в GrandParent инициализирована новым списком / HashSet
public virtual ICollection<ParentFoo> ParentFoos {get; set;} = new List<Parent>();
, а затем
using (var dc = dcHelper_.CreateDataContext())
{
var parent = dc.ParentFoos.Find(pf.Id);
var grandParent = dc.GrandparentFoos.Add(new GrandparentFoo
{
Id = id
});
grandParent.ParentFoos.Add(parent);
parent.GrandparentFoo = grandParent;
}
дочерними элементамиParentFoo не имеет значения, учитывая, что родитель и его связанные дочерние элементы уже существуют в данных.