Parece que sobrescribe directamente SaveChanges en EF para agregar un registrador de auditoría. Consulte el método ApplyAuditLogging para establecer las propiedades de auditoría (creadas, creadas por, actualizadas, actualizadas por) a continuación.Entity Framework 5 Uso de SaveChanges para agregar el registro de auditoría
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 = "????????????????????????";
}
}
El problema es que cómo conseguir la ventanas de inicio de sesión de usuario/nombre de usuario para establecer las propiedades UpdatedBy y CreatedBy del objeto? ¡Por lo tanto, no podría usar esto!
Además, en otro caso, quería agregar automáticamente un nuevo registro de CallHistory a mi contacto; cada vez que se modifica el contacto, se debe agregar un nuevo registro a la tabla secundaria CallHistory. Así que lo hice en InsertOrUpdate del repositorio, pero se siente sucio, sería bueno si pudiera hacerlo a un nivel superior ya que ahora tengo que configurar el usuario actual de la base de datos. De nuevo, aquí el problema es que necesito buscar al usuario de la base de datos para crear un registro CallHistory (SalesRep = User).
El código en mi repositorio hace 2 cosas ahora, 1, se crea una entrada de auditoría sobre el objeto cuando se crea o se actualiza y, 2, sino que también crea una entrada CallHistory cada vez que el contacto se actualiza:
ContactRepository.SetCurrentUser(User).InsertOrUpdate(contact)
con el fin de tener el usuario en el contexto de repositorio para:
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
});
}
}
¿hay una manera de inyectar alguna manera el usuario de windows en la anulación SaveChanges en el DbContext y es también una manera de buscar un usuario de la base de datos basada en la identificación de inicio de sesión de Windows para que pueda configurar el Sal esReptar en mi CallHistory (ver el código anterior)?
Aquí es mi acción en el controlador de aplicación 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);
}
el SamAccountName es modificable, por lo tanto, no es un buen identificador. Utilizo el directorio activo guid que todos los objetos obtienen en su lugar – meffect