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.
InformationsquelleAutor baron | 2011-07-29