В ядре EF, после добавления объекта в один класс, как мне получить доступ к объекту из другого класса без вызова SaveChanges ()? - PullRequest
2 голосов
/ 11 февраля 2020

У меня довольно сложная операция создания, которая разбита на несколько частей в системе, над которой я работаю. Допустим, 3 класса:

  • OperationOrchestrator
  • EntityCreator
  • EntityModifier

Используя экземпляр контекста базы данных, который используется совместно с DI (контекст задается для каждого запроса), Orchestrator вызовет Creator и Modifier создать сложный объект и серию отношений, прежде чем в конечном итоге совершить эту операцию.

Моя проблема заключается в том, что когда EntityModifier пытается получить доступ к сущности, созданной через EntityCreator Я придумываю исключение «Последовательность не содержит элементов». Некоторый псевдокод для иллюстрации:

public class OperationOrchestrator
{
   private IContext _context;
   private IEntityCreator _entityCreator, 
   private IEntityModifier _entityModifier

   public OperationOrchestrator(
       IContext context, 
       IEntityCreator entityCreator, 
       IEntityModifier entityModifier
   )
   {
      //boilerplate var assignment code
   }

   public void CreatePerson(string name, int age)
   {
       var id = _entityCreator.CreatePerson(name);
       _entityModifier.UpdatePersonAge(id, age);
       _context.SaveChanges();
   }
}

public class EntityCreator : IEntityCreator 
{
   private IContext _context;

   public EntityCreator (
       IContext context
   )
   {
      _context = context;
   }

   public Guid CreatePerson(string name)
   {
       var person = new Person {
          Id = Guid.NewGuid(),
          Name = name
       };

       _context.Add(person);
       return person.Id;

   }
}

public class EntityModifier : IEntityModifier
{
   private IContext _context;

   public EntityModifier (
       IContext context
   )
   {
      _context = context;
   }

   public void UpdatePersonAge(Guid id, int age)
   {
       var person = _context.People.Single(x => x.Id == id);
       person.Age = age;
   }
}

Проблема вызова здесь на context.People.Single(x => x.Id == id);. Похоже, что контекст не добавил нового человека в свой People DbSet, хотя экземпляр контекста должен быть одинаковым для всех классов. Кроме того, если я отлаживаю и проверяю локальные переменные, я вижу вновь созданного человека в контексте ChangeTracker.

Наконец, если я вызову SaveChanges() в методе UpdatePersonAge(), непосредственно перед выполнением вызова на context.People.Single(x => x.Id == id); попытка получить человека сразу после этого будет успешной.

Это предназначенный дизайн для Entity Framework или есть какой-то параметр конфигурации, который я могу установить, чтобы переопределить это поведение?

Заранее спасибо!

1 Ответ

2 голосов
/ 11 февраля 2020

Это в соответствии с сводкой от DbSet :

Результаты запроса LINQ для DbSet {TEntity} будут содержать результаты, возвращенные из базы данных, и могут не отражать изменения, сделанные в контексте, которые не были сохранены в базе данных. Например, результаты не будут содержать вновь добавленные объекты и могут по-прежнему содержать объекты, помеченные для удаления.

Сначала вы можете проверить наличие объекта в ChangeTracker, а затем, если его нет, вы можете go в дБ Это также уменьшит количество запросов, сгенерированных вашим приложением.

public class EntityModifier : IEntityModifier
{
    private IContext _context;

    public EntityModifier(IContext context)
    {
        _context = context;
    }

    public void UpdatePersonAge(Guid id, int age)
    {
        var person = _context.ChangeTracker.Entries<Person>().SingleOrDefault(x => x.Id == id) ??
                     _context.People.Single(x => x.Id == id);
        person.Age = age;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...