У меня есть несколько сложных объектов ...
&
Я мог бы глубоко клонировать объект перед внесением изменений в объект, но в моем случае это не работает, потому что некоторые из базовых объектов MVC, которые я использую, например, SelectListItem, не сериализуемы.
Короткий ответ - вещи типа SelectListItem
не принадлежат смешанным в графы сущностей. При условии, что родственники сущности будут загружены, сериализация с глубоким копированием была бы хорошей идеей для отслеживания исходного состояния записи.
То, что вы видите, это дизайн. Ничего не изменилось, если у меня есть коллекция автомобилей, таких как List cars, а затем:
var car1 = cars[0];
var car2 = cars[0];
,, они указывают на одну и ту же машину. EF проверит, знает ли он об идентификаторе автомобиля "n", если нет, загрузит его из БД и вернет. С этого момента он знает об этом, поэтому, если вы снова запросите «n», он вернет ссылку на ту же запись.
За исключением клона глубокой копии, используйте отдельные экземпляры DbContext:
using (var context = new CarContext())
{
using (var originalContext = new CarContext())
{
var originalCar = originalContext.Cars.Single(x => x.CarId == carId);
var car = context.Cars.Single(x => x.CarId == carId);
// Do your thing to Car, reference originalCar for comparisons.
context.SaveChanges();
// Do not call originalContext.SaveChanges()
}
}
Стоимость 2x чтения из базы данных для ваших объектов. Кроме того, вы не можете копировать ссылки из оригинального автомобиля в автомобиль. То есть что-нибудь вроде car.Engine = originalCar.Engine
. Объект, загруженный originalContext, отслеживается originalContext, а не контекстом. Попытка сделать это приведет к ошибкам, связанным с тем, что объект уже отслежен. Попытка отсоединения и повторного присоединения также приведет к ошибкам или нестабильному поведению, такому как повторяющиеся строки или ключевые нарушения.