Динамический прокси C # Entity Framework - Поддерживать отдельные экземпляры объекта в одной записи и отслеживать только изменения в одном? - PullRequest
0 голосов
/ 27 июня 2019

Короче говоря, у меня есть несколько сложных объектов (состоящих из множества подобъектов [некоторые сгенерированные базой данных сначала для объектов EF], коллекций и свойств), которые я использую, и во время операции редактирования я хочу сравнивайте значения отдельных экземпляров объекта вручную или повторно используйте части моего объекта со значениями из базы данных и другими значениями, скажем, из таблицы Excel. Проблема в том, что структура сущностей ссылается на один и тот же динамический прокси между двумя отдельными экземплярами объекта?

Например:

Car myCarOld = dbContext.Cars.Where(c=>c.id == id).FirstOrDefault();
Car myCar = dbContext.Cars.Where(c=>c.id == id).FirstOrDefault();
string oldMake = myCarOld.Make;
myCar.Make = "Toyota"; // Why is this line also updating myCarOld?  Shouldn't they be separate object instances with their own unique values?

if(myCarOld.Make != myCar.Make){
   Console.WriteLine("Hey, they don't match which is what I expect.");
}else{
   Console.WriteLine("Hey, they do match in value, huh?");
}

Вывод "Эй, они совпадают по значению, а?" Как я могу предотвратить это? Я хочу отслеживать изменения только в объекте myCar, не путая старые исходные значения в myCarOld. Я мог бы глубоко клонировать объект, прежде чем вносить изменения в объект, но в моем случае это не работает, потому что некоторые из базовых объектов MVC, которые я использую, например SelectListItem, не сериализуемы.

Я читал кое-что об отключении объекта контекста context.Entry(personEntity).State = EntityState.Detached;, но мне кажется, что нужно проделать большую работу для всех объектов EF в моем пользовательском объекте? Я даже не уверен, что это поможет в моем случае, и я не уверен, что я описываю то, что я собираюсь сделать правильно. Я не совсем понимаю. Пожалуйста, помогите прояснить это. Я ценю любую помощь.

Похоже на Entity Framework и поддерживает два экземпляра сущности , но есть ли способ сделать это без изменения запроса? Я просто хочу взять результат и сохранить его как отдельный объект со своим собственным набором уникальных значений.

1 Ответ

1 голос
/ 27 июня 2019

У меня есть несколько сложных объектов ...

&

Я мог бы глубоко клонировать объект перед внесением изменений в объект, но в моем случае это не работает, потому что некоторые из базовых объектов 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, а не контекстом. Попытка сделать это приведет к ошибкам, связанным с тем, что объект уже отслежен. Попытка отсоединения и повторного присоединения также приведет к ошибкам или нестабильному поведению, такому как повторяющиеся строки или ключевые нарушения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...