Dường như chuyển tiếp thẳng tiến lên SaveChanges trong EF để thêm trình kiểm tra logger. Xem phương thức ApplyAuditLogging để thiết lập các thuộc tính kiểm toán (được tạo, tạo, cập nhật, cập nhật) bên dưới.Entity Framework 5 Sử dụng SaveChanges để thêm nhật ký kiểm tra
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 = "????????????????????????";
}
}
Vấn đề là cách để người dùng đăng nhập/đăng nhập để đặt thuộc tính UpdatingBy và CreatedBy của đối tượng? Do đó tôi không thể sử dụng điều này!
Ngoài ra, trong trường hợp khác, tôi muốn tự động thêm bản ghi CallHistory mới vào Liên hệ của mình; bất cứ khi nào liên lạc được sửa đổi, một bản ghi mới cần phải được thêm vào bảng con CallHistory. Vì vậy, tôi đã làm nó trong InsertOrUpdate của Kho lưu trữ nhưng nó cảm thấy bẩn, sẽ là tốt đẹp nếu tôi có thể làm điều đó ở một cấp độ cao hơn như bây giờ tôi phải thiết lập người dùng hiện tại từ cơ sở dữ liệu. Một lần nữa vấn đề ở đây là tôi cần lấy người dùng từ cơ sở dữ liệu để tạo một bản ghi CallHistory (SalesRep = Người dùng).
Các mã trong Repository của tôi làm 2 điều bây giờ, 1, nó tạo ra một mục kiểm toán trên các đối tượng khi nó được tạo ra hoặc cập nhật và, 2, nó cũng tạo ra một mục CallHistory bất cứ khi nào Liên được cập nhật:
ContactRepository.SetCurrentUser(User).InsertOrUpdate(contact)
để có người dùng trong bối cảnh Repository cho:
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
});
}
}
có một cách nào đó tiêm cho người sử dụng cửa sổ vào override SaveChanges trong DbContext và có cũng là một cách để lấy một tài khoản từ cơ sở dữ liệu dựa trên windows logon id để tôi có thể thiết lập Sal esRep trên CallHistory của tôi (xem mã trên)?
Đây là hành động của tôi trên bộ điều khiển trên ứng dụng MVC:
[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);
}
SamAccountName có thể thay đổi do đó không phải là số nhận dạng tốt. Tôi sử dụng hướng dẫn thư mục hoạt động mà tất cả các đối tượng nhận được thay vào đó – meffect