В ядре EF, после добавления сущности в один класс, как мне получить доступ к сущности из другого класса без вызова SaveChanges ()?

У меня есть довольно сложная операция создания, которая разбита на несколько частей в системе, над которой я работаю. Предположим, 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 ответ


Это дизайн в соответствии с резюме от DbSet :

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

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

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;
    }
}

Есть идеи?

10000