2013-06-03 2 views
1

Когда запись обновляется в моей базе данных, мне нужно иметь возможность сохранять, кто ее редактировал.Entity Framework Сохранение пользователя при изменении записи

В настоящее время в моем Repository я это делаю

pt.ModifiedBy = HttpContext.Current.User.Identity.Name; 

Там должен быть лучший способ сделать это, или это единственный способ?

+0

Если ваше приложение не войти в базу данных по регистрации пользователя (олицетворения), единственное, что вы можете это установить ModifiedBy свойство в вашем приложении. –

+1

объедините оба ответа ... не плотно соединяйте и помещайте приятную функцию в свой базовый класс хранилища –

ответ

3

IMO лучший вариант - это обработать весь аудит в одном месте - ваш блок работы (DbContext). Это легко достигается тем, что все объекты Poco реализуют общий интерфейс, такой как IEntity.

Вот пример:

public class MyContext : DbContext 
{ 
    public override int SaveChanges() 
    { 
     //you may need this line depending on your exact configuration 
     //ChangeTracker.DetectChanges(); 
     foreach (DbEntityEntry o in GetChangedEntries()) 
     { 
      IEntity entity = o.Entity as IEntity; 
      entity.ModifiedBy = HttpContext.Current.User.Identity.Name; 
     } 
     return base.SaveChanges(); 
    } 

    private IEnumerable<DbEntityEntry> GetChangedEntries() 
    { 
     return new List<DbEntityEntry>(
      from e in ChangeTracker.Entries() 
      where e.State != System.Data.EntityState.Unchanged 
      select e); 
    } 
} 
5

С помощью HttpContext.Current.User вы плотно сцепных вашего DbContext с HttpContext, которая не является хорошей идеей в случае, если вы будете подвергать DbContext к не-веб-среде (модульное тестирование, WCF, WPF и т. Д.).

Вы можете использовать System.Security.Principal.IIdentity вместо этого, просто нравится выставлены в ASP.NET (System.Web.HttpContext.Current.User.Identity) WCF (System.ServiceModel.OperationContext.Current.ServiceSecurityContext.PrimaryIdentity) и резьбы (Thread.CurrentPrincipal.Identity).

Затем введите свой DbContext в свой конструктор и каждый раз, когда инициализированный контекст передает соответствующий IIdentity (из вашего текущего контекста).

Например (на основе @qujck ответа):

public class MyContext : DbContext 
{ 
    private readonly IIdentity _identity; 

    public DbContext(IIdentity identity) 
    { 
      this._identity = identity; 
    } 

    public override int SaveChanges() 
    { 
     //you may need this line depending on your exact configuration 
     //ChangeTracker.DetectChanges(); 
     foreach (DbEntityEntry o in GetChangedEntries()) 
     { 
      IEntity entity = o.Entity as IEntity; 
      entity.ModifiedBy = this._identity.Name; 
     } 
     return base.SaveChanges(); 
    } 
} 

// Usage (ASP.NET): 
var context = new DbContext(System.Web.HttpContext.Current.User.Identity); 
+0

Хороший совет по разделению проблем – user919426