EF Core 3.1 - отключенный график - свойство навигации - исключение объекта уже отслежено - путь вперед - PullRequest
1 голос
/ 01 мая 2020

У меня есть следующий граф сущностей:

Клиент -> Имеет несколько адресов -> У каждого адреса есть свойство навигации Страна

Я использовал строительные леса для обратного проектирования классов, поэтому проблем с настройками нет.

public class Customers {
   public Customers() {
      Addresses = new List<Addresses>();
   }

   public int CustomerId {
      get; set;
   }

   public string FirstName {
      get; set;
   }

   public string LastName {
      get; set;
   }

   public int CustomerTypeId {
      get; set;
   }

   public CustomerTypes CustomerType {
      get; set;
   }

   public ICollection<Addresses> Addresses {
      get; set;
   }
}

public class Addresses {
   public int AddressId {
      get; set;
   }

   public int CustomerId {
      get; set;
   }

   public int AddressTypeId {
      get; set;
   }

   public string ZipPostalcode {
      get; set;
   }

   public int CountryId {
      get; set;
   }

   public AddressTypes AddressType {
      get; set;
   }

   public Countries Country {
      get; set;
   }
}

public class Countries {
   public int CountryId {
      get; set;
   }

   public string Alpha2Code {
      get; set;
   }

   public string Alpha3Code {
      get; set;
   }

   public string EnglishName {
      get; set;
   }

   public string FrenchName {
      get; set;
   }
}

У меня может быть клиент с двумя адресами - каждый с разными типами адресов, такими как «Дом» и «Бизнес», - но в одной стране (скажем, в США).

Ниже приведен упрощенный код, который вызывается для обновления графика - просто чтобы показать поток, я сначала извлекаю график клиента, вносю изменения и пытаюсь обновить (каждое действие в новом DbContext):

public static void Update_Using_TrackGraph(DbContextOptions<PolyglotContext> contextOptions) {
   Customers customer;

   using (var context = new PolyglotContext(contextOptions)) {
      customer = context.Customers
                        .Include(x => x.CustomerType)
                        .Include(x => x.Addresses)
                              .ThenInclude(x => x.AddressType)
                        .Include(x => x.Addresses)
                              .ThenInclude(x => x.Country)
                        .AsNoTracking()
                        .SingleOrDefault(x => x.CustomerId == 1);
   }

   customer.EmailAddress = "new.email@avengers.com";
   foreach (var address in customer.Addresses)
      address.Line3 = "Thor Town";

   using var ctx = new PolyglotContext(contextOptions);

   ctx.ChangeTracker.Tracked += (s, e) => {
      Console.WriteLine($"{e.Entry.Entity}: {e.Entry.State}");
   };

   ctx.ChangeTracker.StateChanged += (s, e) => {
      Console.WriteLine($"{e.Entry.Entity}: {e.OldState} - {e.NewState}");
   };

   ctx.ChangeTracker
      .TrackGraph(customer, e => {
         e.Entry.State = e.Entry.IsKeySet ? EntityState.Modified : EntityState.Added;
      });

   ctx.SaveChanges();
}

Когда я пытаюсь прикрепить график, я получаю следующую ошибку:

The instance of entity type 'Countries' cannot be tracked because another instance with the same key value for {'CountryId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

После некоторого поиска я понимаю, что эта ошибка ожидается с EF 3.1. Здесь обсуждаются здесь и здесь .

Вопрос - Как мне решить эту проблему? Я попробовал следующие опции, и все они работают:

Опция 1 - Я изменил поведение TrackGraph следующим образом:

e.Entry.State = e.Entry.Entity.GetType() == typeof(Countries) ? EntityState.Detached
                  : (e.Entry.IsKeySet ? EntityState.Modified : EntityState.Added);

Опция 2 - При обновлении указывайте, что объект обновляется, а график не обновляется. Это означало бы обновление одной сущности за один раз

Есть ли другие доступные варианты? Я ищу опыт от тех, кто работал над подобным обновлением графика schenar ios?

Большое спасибо,

...