2016-06-23 4 views
0

Я пытаюсь использовать миграции EF для сборки/загрузки моей базы данных, но мой DbContext вызывает ошибку, когда я использую команду update-database.Получение информации о пользователе в DbContext

Введенный мной DbContext имеет два конструктора: один принимает аргументы, а другой принимает интерфейс IUserContext. Интерфейс IUserContext возвращает имя пользователя в виде строки. IUserContext используется в методе SaveChanges() для установки пользовательских полей аудита (например, CreatedBy, UpdBy), общих для всех моих объектов. В зависимости от реализации интерфейса IUserContext имя пользователя может быть извлечено из HttpContext (в приложении mvc), WindowsIdentity (в консольном приложении) и т. Д.

Если пользователь пытается вызвать SaveChanges в DbContext и IUserContext не установлен, он генерирует исключение. В принципе, Мне не нужны изменения, сохраненные в DbContext, если имя пользователя не может быть предоставлено интерфейсом IUserContext для целей записи, кто вносит изменения. Если DbContext используется только для запросов, использование конструктора no-args не является проблемой, поскольку IUserContext используется только во время SaveChanges.

Когда я пытаюсь использовать команду update-database, DbMigrationsConfiguration присваивается экземпляр созданного DbContext с использованием конструктора no-args. Поэтому он генерирует исключение, когда пытается вызвать SaveChanges DbContext после метода Seed().

Вопрос: Как передать IUserContext моему DbContext поэтому команда обновления базы данных, не подведет и, что более важно, быть в состоянии установить соответствующие поля сущностей с именем пользователя высева изменения? Есть ли какая-либо форма DI или другая настройка, которую я могу выполнить в DbMigrationsConfiguration? Должен ли я просто добавить метод доступа IUserContext к DbContext, чтобы IUserContext мог быть установлен за пределами конструктора?

Может быть, я должен задать больший вопрос: Что является лучшим (наиболее общим?) Способом передачи информации пользователя в DbContext для целей записи, который делают изменения?

Я подумал о том, чтобы переместить эту логику на бизнес-уровень моего приложения, но представляется так удобно инкапсулировать его в SaveChanges DbContext (тем более, когда отслеживание изменений включено).

ответ

0

Мы имеем аналогичную ситуацию, когда мы записываем измененного пользователя в SaveChanges() override. То, что мы закончили, было создание BaseWrapper и использование IoC для его заполнения. Во второй части создается MigrationsContextFactory, которые будут использоваться для создания контекста. Этот класс живет в той же папке, что и наш ApplicationDbContext.

using System.Data.Entity.Infrastructure; 

namespace MyApp.Data 
{ 
    public class MigrationsContextFactory : IDbContextFactory<ApplicationDbContext> 
    { 
     public ApplicationDbContext Create() 
     { 
      return new ApplicationDbContext(new HttpContextBaseWrapper()); 
     } 
    } 
} 

public class HttpContextBaseWrapper : IHttpContextBaseWrapper 
{ 
    public string UserName 
    { 
     get 
     { 
      if (HttpContext.Current == null || HttpContext.Current.User == null) 
       return string.Empty; 
      return HttpContext.Current.User.Identity.Name; 
     } 
    } 
} 

https://marazt.wordpress.com/2015/01/09/entity-framework-dbcontext-idbcontextfactory-and-codefirst-migration-problem/