2

Я относительно новичок в EF7 и слышал, что инжекция DbContexts зависимостей в конструктор Controller - хороший способ получить DbContext для использования в рамках определенных методов Action. Однако существует множество ситуаций, когда инъекция зависимостей невозможна (например, доступ к Db в обычных классах), и шаблон using(VectorDbContext dbContext...) должен использоваться.Зависимость вложенности DbContext пуст после заполнения DbContext, созданного с помощью нового (EF7, ASP.NET 5, vnext)

У меня возникла проблема, при которой добавление данных в DbContext, созданный с помощью шаблона using, невозможно получить через контекст, который был введен в зависимость. DbContext - это простая база данных InMemory, используемая для тестирования - она ​​ничего не связывает.

Вот код, который добавляет объекты в DbContext, для тестирования я называю это Startup.cs:

using (ExampleDbContext dbContext= new ExampleDbContext()) { 
    dbContext.Things.Add(
     new Thing() { 
      Stuff= "something" 
     }); 

    dbContext.SaveChanges(); 
} 

Вот код доступа в контроллере:

public class ExampleController : Controller { 
    public ExampleController(ExampleDbContext exampleDbContext) { 
     this.ExampleDbContext= exampleDbContext; 
    } 

    public ExampleDbContext ExampleDbContext { get; set; } 

    public async Task<IActionResult> ExampleAction() { 

     // new DbContext: 
     using(ExampleDbContext dbContext = new ExampleDbContext()) { 
      var List1 = (await dbContext.Things 
       .AsNoTracking() 
       .ToListAsync()); 
     } 

     // Injected DbContext: 
     var List2 = (await this.ExampleDbContext.Things 
      .AsNoTracking() 
      .ToListAsync()); 
    } 
} 

Когда переходя через List1 есть ожидаемый один элемент в нем, но List2 всегда пуст!

Что я делаю неправильно? Похоже, что DbContexts не синхронизированы каким-то образом, как Dependency Injection создает DbContext/откуда он?

EDIT: Я просто сделал некоторые дополнительные испытания и подтвердил, что любые объекты, добавленные в DbContext созданного с new видны только в new, и объекты, добавленные в инжектированных DbContext видны только в инжектированных DbContext, что привели меня к что они подключаются к различным базам данных баз данных, но я не могу подтвердить.

+1

Что касается инъекции DbContext: я реализовал SimpleInjector, чтобы сделать это для меня, следуя нашему уважаемому S.O. член [Steven] (http://stackoverflow.com/users/264697/steven) и его [блог] (https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92) о как его реализовать. Я нашел его подход очень полезным, может быть, вы сможете решить, как решить свои проблемы с его пошаговым руководством! – Adimeus

+0

В настоящее время я использую MVC6, встроенный в Injector Dependency Injector, по-видимому, он создает объекты в области запроса (как описано здесь) (http://blogs.msdn.com/b/webdev/archive/2014/06/17/dependency-injection- in-asp-net-vnext.aspx) и после этого удаляет их. Не знаю, почему один и тот же DbContext представляет два разных представления данных. Спасибо за ссылку в блоге, я мог бы реализовать это для некоторого более тонкого контроля. – Ryan

+1

@Ryan - Это не тот же DbContext. Вы создали новый. Это два отдельных DbContexts, поэтому, конечно, они содержат разные наборы данных в своих внутренних кэшах. Я не знаю, почему вы создаете новый экземпляр. –

ответ

2

Возможно, я ошибаюсь, но я полагаю, что при создании нового экземпляра DbContext в коде вы используете конструктор без параметров, который устанавливает базовую строку подключения для некоторого значения по умолчанию. Однако DI-инъецируемый DbContext может быть разрешен с использованием другого конструктора с другой строкой передачи, переданной явно.

Вот пример единства конфигурации, который явно указывает параметр конструктора:

<register type="DbContext, [assembly-name]" mapTo="DbContext, [assembly-name]"> 
<constructor> 
    <param name="nameOrConnectionString" value="Test"/> 
</constructor> 
</register> 

Так что я бы проверить конфигурацию вашего контейнера.

+0

Это определенная возможность. Я знаю, что это определенно происходит, когда методы параметрирования расширения используются в 'DbContext'' OnConfiguring' для настройки соединения. Я работал над этим ранее, вручную предоставляя строку соединения, то есть 'options.UseSqlServer (Configuration.Get (" Data: DefaultConnection: ConnectionString "));' а не 'options.UseSqlServer()'. Однако, похоже, что 'UseInMemoryStore()' не имеет параметризованных перегрузок, поэтому я ничего не могу с этим поделать ... Я собираюсь пройти через некоторый исходный код vNext. – Ryan

Смежные вопросы