La mise en œuvre de Journal d'Audit / Changer l'Histoire avec MVC & Entity Framework
Je suis bâtiment dans un, Changer l'Histoire /Journal d'Audit pour mon MVC application qui est à l'aide de Entity Framework.
Spécifique, la méthode edit public ActionResult Edit(ViewModel vm)
, nous trouvons l'objet que nous essayons de mettre à jour, et ensuite utiliser TryUpdateModel(object)
de transposer les valeurs de la forme à l'objet que nous essayons de mettre à jour.
Je veux connecter un changement quand tout le champ de l'objet de modifications. Donc, fondamentalement, ce que j'ai besoin d'une copie de l'objet avant de l'éditer et de le comparer après la TryUpdateModel(object)
a fait son travail. c'est à dire
[HttpPost]
public ActionResult Edit(ViewModel vm)
{
//Need to take the copy here
var object = EntityFramework.Object.Single(x=>x.ID = vm.ID);
if (ModelState.IsValid)
{
//Form the un edited view model
var uneditedVM = BuildViewModel(vm.ID); //this line seems to confuse the EntityFramework (BuildViewModel() is used to build the model when originally displaying the form)
//Compare with old view model
WriteChanges(uneditedVM, vm);
...
TryUpdateModel(object);
}
...
}
Mais le problème est quand le code récupère les "inédits vm", c'est à l'origine de certains changements inattendus dans le EntityFramework - de sorte que TryUpdateModel(object);
jette un UpdateException
.
La question est donc - dans cette situation - comment puis-je créer une copie de la object
à l'extérieur de EntityFramework de comparer pour le changement/l'historique d'audit, de manière à ne pas affecter ou modifier l'
EntityFramework à tous les
edit: Ne voulez pas utiliser des déclencheurs. Besoin d'enregistrer le nom de l'utilisateur qui l'a fait.
edit1: à l'Aide de EFv4, pas trop sûr de la façon d'aller sur la substitution SaveChanges()
mais il peut être une option
Cette route semble aller nulle part, pour une simple exigence! J'ai finalement réussi à le remplacer correctement, mais maintenant, je reçois une exception avec ce code:
public partial class Entities
{
public override int SaveChanges(SaveOptions options)
{
DetectChanges();
var modifiedEntities = ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
foreach (var entry in modifiedEntities)
{
var modifiedProps = ObjectStateManager.GetObjectStateEntry(entry).GetModifiedProperties(); //This line throws exception The ObjectStateManager does not contain an ObjectStateEntry with a reference to an object of type 'System.Data.Objects.EntityEntry'.
var currentValues = ObjectStateManager.GetObjectStateEntry(entry).CurrentValues;
foreach (var propName in modifiedProps)
{
var newValue = currentValues[propName];
//log changes
}
}
//return base.SaveChanges();
return base.SaveChanges(options);
}
}
- Essayez cette pastebin.com/puygwzyb
- Ou... vous n'avez pas de créer!... juste obtenir ce package nuget à la place. nuget.org/packages/trackerenableddbcontext
- Ouai ça va résoudre le problème en ajoutant une tonne plus de ballonnements à votre solution lorsque ce problème peut être résolu avec très peu de code. Je ne comprends pas pourquoi les gens se sentent le besoin de tirer dans les paquets pour littéralement tout dernièrement, au lieu de simplement écrire quelques lignes.
Vous devez vous connecter pour publier un commentaire.
SI vous utilisez EF 4 vous pouvez vous abonner à la
SavingChanges
événement.Depuis
Entities
est une classe partielle vous pouvez ajouter des fonctionnalités supplémentaires dans un fichier séparé. Donc, créez un nouveau fichier nomméEntities
et il y en œuvre partielle de la méthodeOnContextCreated
pour brancher l'événementSi vous utilisez EF 4.1, vous pouvez aller à travers les cet article pour extraire les modifications
ObjectContext
puis-je configurer le gestionnaire d'événement dans cette classe ?ObjectContext
. au lieu de cela, vous devez vous abonner à votreEntities
constructeur. J'ai édité ma réponseEntities.SaveChanges();
et ont un point d'arrêt sur lacontext_SavingChanges()
méthode, il n'entre jamais!Voir FrameLog, une Entité Cadre de la journalisation de la bibliothèque que j'ai écrit à cette fin. Il est open-source, y compris pour un usage commercial.
Je sais que vous préférez viens de voir un extrait de code montrant comment le faire, mais de traiter correctement tous les cas pour l'exploitation forestière, y compris la relation changements et plusieurs-à-plusieurs modifications, le code devient assez grand. J'espère que la bibliothèque sera un bon choix pour vos besoins, mais si vous pouvez librement adapter le code.
FrameLog pouvez le journal des modifications à tous les scalaires et les propriétés de navigation, et vous permet également de spécifier un sous-ensemble de ce que vous êtes intéressé dans l'exploitation forestière.
Il y a un article avec une cote élevée ici au codeproject: La mise en œuvre de la Piste d'Audit à l'aide de Entity Framework . Il semble faire ce que vous voulez. J'ai commencé à utiliser cette solution dans un projet. J'ai d'abord écrit déclenche en T-SQL dans la base de données, mais il était trop difficile de les maintenir avec des changements dans le modèle d'objet qui se passe tout le temps.