Entity Framework 4.1 DbContext Remplacer SaveChanges à la Vérification de la Propriété de Changer
Je suis en train de mettre en œuvre une contrainte 'journal d'audit" de la propriété des changements de propriétés dans un ensemble de classes. J'ai réussi à trouvé comment mettre CreatedOn|ModifiedOn type de propriétés, mais je suis à défaut de trouver comment "trouver" la propriété qui a été modifié.
Exemple:
public class TestContext : DbContext
{
public override int SaveChanges()
{
var utcNowAuditDate = DateTime.UtcNow;
var changeSet = ChangeTracker.Entries<IAuditable>();
if (changeSet != null)
foreach (DbEntityEntry<IAuditable> dbEntityEntry in changeSet)
{
switch (dbEntityEntry.State)
{
case EntityState.Added:
dbEntityEntry.Entity.CreatedOn = utcNowAuditDate;
dbEntityEntry.Entity.ModifiedOn = utcNowAuditDate;
break;
case EntityState.Modified:
dbEntityEntry.Entity.ModifiedOn = utcNowAuditDate;
//some way to access the name and value of property that changed here
var changedThing = SomeMethodHere(dbEntityEntry);
Log.WriteAudit("Entry: {0} Origianl :{1} New: {2}", changedThing.Name,
changedThing.OrigianlValue, changedThing.NewValue)
break;
}
}
return base.SaveChanges();
}
}
Alors, est-il un moyen d'accéder à la propriété qui a changé avec ce niveau de détail, en EF 4.1 DbContext?
Vous devez vous connecter pour publier un commentaire.
Très, très bonne idée:
Je n'ai aucune idée si ce serait vraiment travailler dans le détail, mais c'est quelque chose que je voudrais essayer dans un premier temps. Bien sûr, il pourrait y avoir plus d'une propriété qui a changé, donc la boucle et peut-être de multiples appels de
WriteAudit
.La réflexion choses à l'intérieur d'SaveChanges pourrait devenir un spectacle de cauchemar même si.
Modifier
C'est peut-être mieux pour accéder au sous-jacente
ObjectContext
. Alors quelque chose comme ceci est possible:J'ai utilisé moi-même en EF 4.0. Je ne peux pas trouver une méthode pour
GetModifiedProperties
(qui est la clé pour éviter le code de réflexion) dans leDbContext
API.Edit 2
Important: Lorsque l'on travaille avec des entités POCO le code ci-dessus doit appeler
DbContext.ChangeTracker.DetectChanges()
au début. La raison en est quebase.SaveChanges
est appelé trop tard ici (à la fin de la méthode).base.SaveChanges
appelsDetectChanges
en interne, mais parce que nous voulons analyser et enregistrer les modifications avant de, nous devons appelerDetectChanges
manuellement de sorte que EF pouvez trouver toutes les propriétés modifiées et définir les états dans le système de suivi de changement correctement.Il y a des situations où le code permet de travailler sans appel
DetectChanges
, par exemple si DbContext/DbSet méthodes commeAdd
ouRemove
sont utilisés après la dernière propriété des modifications sont apportées depuis ces méthodes ont également appelDetectChanges
en interne. Mais si, par exemple, une entité est juste chargé de DB, quelques propriétés sont modifiées et puis ce dérivéSaveChanges
est appelée, la détection automatique des changements n'arriverait pas avantbase.SaveChanges
, ce qui a finalement abouti dans les entrées de journal pour les propriétés modifiées.J'ai mis à jour le code ci-dessus en conséquence.
DbContext
) et POCO. Vous pouvez faire quelque chose de semblable, mais pour <= EF 4.0 (ObjectContext
), la seule différence est que vous ne pas écraserSaveChanges
mais de mettre en place un gestionnaire d'événements (OnSavingChanges
ou similaire, je ne me souviens pas exactement).Vous pouvez utiliser les méthodes Slauma donne à penser, mais au lieu de l'annulation de la
SaveChanges()
méthode, vous pouvez gérer leSavingChanges
cas pour beaucoup plus de facilité de mise en œuvre.SavingChanges
gestionnaire, j'ai oublié que. Mais pourquoi faut-il rendre les choses plus faciles? N'est-il pas fondamentalement la même, ce que vous devez faire pour écrire le journal?SaveChanges
de la classe de base (ajouter). (C'était parce que j'ai copié les principales parties de l'extrait de monSavingChanges
gestionnaire.)DbContext.Entry(object)
méthode pour saisir l'entité modifier les informations de suivi, qui contient unState
de la propriété.Il semble Slauma la réponse n'a pas de vérification des changements à l'intérieur des propriétés d'un type complexe de la propriété.
Si c'est un problème pour vous, ma réponse ici pourrait être utile. Si la propriété est complexe et qu'il a changé, je serialise l'ensemble du complexe de la propriété dans le journal d'audit d'enregistrement. Ce n'est pas la solution la plus efficace mais il n'est pas trop mauvais et il fait le travail.
J'aime vraiment Slauma de la solution. D'habitude, je préfère garder une trace de la modification de la table et les dossiers de la clé primaire(s) tho. C'est une méthode très simple que vous pouvez utiliser pour faire cela, appelant
getEntityKeys(entry)
Voir À l'aide de Entity Framework 4.1 DbContext le Suivi des modifications pour l'enregistrement d'Audit.
Avec DbEntityEntry. Détail de vérification pour ajouter, supprimer, modifier