Добавление объекта в коллекцию удаляет его из другого (Entity Framework).

#entity-framework #collections

#сущность-фреймворк #Коллекции

Вопрос:

ребята, у меня очень странная проблема, о которой никто из моей компании не знает.

У меня есть коллекция внутри одного объекта, которую я создал вручную:

 Cost cost = new Cost 
        {
            ...
        };
cost.Formulas.Add(new Formula()
                {
                    CostID = cost.ID,
                    FieldName = "Distance",
                    Formula1 = "12 2",
                });
 

Затем я получил другой объект с тем же типом и идентификатором из контекста:

 Cost updatingCost = context.Costs.Include("Formulas").FirstOrDefault(c => c.ID == cost.ID);
 

И, наконец, я это делаю:

 updatingCost.Formulas.Add(cost.Formulas.ToList()[0]);
 

А вот и волшебство! После этой строки стоимость.Формулы больше не содержат эту Формулу!!

 cost.Formulas.Count = 0
 

Что делает этот метод ICollection.Добавить() сделать? Почему он удаляет объект из другой коллекции? Это сводит меня с ума, пожалуйста, помогите понять это!

Комментарии:

1. Это должно иметь какое-то отношение к исправлению отношений. Но странный вопрос заключается в том, что, если я правильно понимаю, формула удаляется из объекта стоимости, который не привязан к контексту. Это правильно? Если бы объект стоимости был привязан к контексту, это было бы абсолютно нормально.

2. Вы правы, формула была удалена из не привязанного к контекстному объекту «стоимость»! Кроме того, в формуле не было никакого EntityKey, а CostID был таким же, как в «updatingCost»

Ответ №1:

На самом деле это довольно просто. Добавляя новую формулу к другому Cost объекту updatingCost , EF изменяет значение внешнего ключа CostID на значение updatingCost.ID .

Это связано с тем, что EF выполняет исправление отношений много раз, когда объекты обрабатываются в коде. Этот процесс гарантирует, что значения идентификаторов примитивов, ссылки на объекты и содержимое коллекции совпадают.

Комментарии:

1. Спасибо за ответ, но идентификатор объекта «cost» и объекта «updatingCost» одинаковы. Итак, если EF что-то изменил — это изменило EntityKey, а не идентификатор…

2. Но это нормально, если все объекты привязаны к одному и тому же контексту, как я сказал в своем комментарии. Однако, как это возможно, что это происходит с объектом, который не привязан к контексту?

3. О, я думаю, я начинаю понимать… Если это будет одна и та же формула с некоторым идентификатором, EF определяет, что это должна быть только одна формула, привязанная к стоимости, и было бы странно, если бы у другой стоимости она тоже была… Круто!

4. Да, проблема в том, что объект находится вне контекста. Для меня это была просто временная коллекция для клонирования объектов, но EF так не думает 🙂

5. Возможно, даже cost объект привязывается к контексту при выполнении updatingCost.Formulas.Add инструкции, но как другой объект (с временным ключом), чем updatingCost . Вы могли бы проверить объекты внутри context.Costs.Local .