当我的数据库中的记录更新时,我需要能够保存编辑它的人。
目前在我的存储库中我这样做
pt.ModifiedBy = HttpContext.Current.User.Identity.Name;
必须有更好的方法来做这个或这是唯一的方法吗?
答案 0 :(得分:5)
使用HttpContext.Current.User
,您将DbContext
与HttpContext
紧密联系起来,这不是一个好主意,以防您将DbContext
暴露给非网络环境(UnitTesting,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
在其构造函数中,并且每当初始化的上下文传递相应的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);
答案 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);
}
}