gpt4 book ai didi

c# - Entity Framework 5 使用 SaveChanges 添加审计日志

转载 作者:太空狗 更新时间:2023-10-29 21:28:53 25 4
gpt4 key购买 nike

似乎直接覆盖 EF 中的 SaveChanges 以添加审计记录器。请参阅下面的 ApplyAuditLogging 方法来设置审计属性(创建、创建、更新、更新)。

   public override int SaveChanges()
{
var autoDetectChanges = Configuration.AutoDetectChangesEnabled;

try
{
Configuration.AutoDetectChangesEnabled = false;
ChangeTracker.DetectChanges();
var errors = GetValidationErrors().ToList();
if(errors.Any())
{
throw new DbEntityValidationException("Validation errors were found during save: " + errors);
}

foreach (var entry in ChangeTracker.Entries().Where(e => e.State == EntityState.Added || e.State == EntityState.Modified))
{
ApplyAuditLogging(entry);
}

ChangeTracker.DetectChanges();

Configuration.ValidateOnSaveEnabled = false;

return base.SaveChanges();
}
finally
{
Configuration.AutoDetectChangesEnabled = autoDetectChanges;
}
}

private static void ApplyAuditLogging(DbEntityEntry entityEntry)
{

var logger = entityEntry.Entity as IAuditLogger;
if (logger == null) return;

var currentValue = entityEntry.Cast<IAuditLogger>().Property(p => p.Audit).CurrentValue;
if (currentValue == null) currentValue = new Audit();
currentValue.Updated = DateTime.Now;
currentValue.UpdatedBy = "???????????????????????";
if(entityEntry.State == EntityState.Added)
{
currentValue.Created = DateTime.Now;
currentValue.CreatedBy = "????????????????????????";
}
}

问题是如何获取windows用户登录/用户名来设置对象的UpdatedBy和CreatedBy属性?因此我不能使用它!

此外,在另一种情况下,我想自动将新的 CallHistory 记录添加到我的联系人中;每当修改联系人时,都需要在子表 CallHistory 中添加一条新记录。所以我在 Repository 的 InsertOrUpdate 中做了它,但感觉很脏,如果我能在更高级别做它会很好,因为现在我必须从数据库中设置当前用户。这里的问题是我需要从数据库中获取用户以创建 CallHistory 记录 (SalesRep = User)。

我的存储库中的代码现在做了两件事,1,它在创建或更新对象时在对象上创建了一个审计条目,2,每当联系人更新时,它也创建了一个 CallHistory 条目:

ContactRepository.SetCurrentUser(User).InsertOrUpdate(contact)

为了让用户在 Repository 上下文中:

    var prop = typeof(T).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);

if (prop.GetValue(entity, null).ToString() == "0")
{
// New entity
_context.Set<T>().Add(entity);
var auditLogger = entity as IAuditLogger;
if (auditLogger != null)
auditLogger.Audit = new Audit(true, _principal.Identity.Name);
}
else
{
// Existing entity
_context.Entry(entity).State = EntityState.Modified;
var auditLogger = entity as IAuditLogger;
if (auditLogger != null && auditLogger.Audit != null)
{
(entity as IAuditLogger).Audit.Updated = DateTime.Now;
(entity as IAuditLogger).Audit.UpdatedBy = _principal.Identity.Name;
}

var contact = entity as Contact;
if (_currentUser != null)
contact.CallHistories.Add(new CallHistory
{
CallTime = DateTime.Now,
Contact = contact,
Created = DateTime.Now,
CreatedBy = _currentUser.Logon,
SalesRep = _currentUser
});
}
}

有没有办法以某种方式将 Windows 用户注入(inject)到 DbContext 中的 SaveChanges 覆盖中,还有没有办法根据 Windows 登录 ID 从数据库中获取用户,这样我就可以在我的 CallHistory 上设置 SalesRep(见上文)代码)?

这是我在 MVC 应用程序上对 Controller 的操作:

[HttpPost]
public ActionResult Create([Bind(Prefix = "Contact")]Contact contact, FormCollection collection)
{
SetupVOs(collection, contact, true);
SetupBuyingProcesses(collection, contact, true);

var result = ContactRepository.Validate(contact);

Validate(result);

if (ModelState.IsValid)
{
ContactRepository.SetCurrentUser(User).InsertOrUpdate(contact);
ContactRepository.Save();
return RedirectToAction("Edit", "Contact", new {id = contact.Id});
}

var viewData = LoadContactControllerCreateViewModel(contact);

SetupPrefixDropdown(viewData, contact);

return View(viewData);
}

最佳答案

好吧,简单而懒惰的方法是从您的审计代码中访问 HttpContext.Current.User.Identity.Name。但是,这将创建对 System.Web.* 的依赖性,如果您有一个很好的分层应用程序,这可能不是您想要的(如果您使用实际的单独层,它就不会起作用)。

一个选项是,不覆盖 SaveChanges,而是创建一个采用您的用户名的重载。然后你做你的工作,然后调用真正的 SaveChanges。缺点是有人可能错误地(或故意地)调用 SaveChanges()(真正的)并绕过审计。

更好的方法是简单地向您的 DbContext 添加一个 _currentUser 属性并使用构造函数将其传入。然后当您创建上下文时,您只需在此时传入用户。不幸的是,您无法真正从构造函数中查找数据库中的用户。

但是您可以简单地保存 ContactID 并添加它而不是整个联系人。您的联系人应该已经存在。

关于c# - Entity Framework 5 使用 SaveChanges 添加审计日志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12573568/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com