Trouver les différences entre deux entités de même type
Je suis en train de travailler sur un mvc3 web app. Lorsque l'utilisateur met à jour quelque chose, je veux comparer les anciennes données vers le nouveau, l'utilisateur est de l'entrée et pour chaque champ est différent de les ajouter à un journal pour créer un journal d'activité.
Droit maintenant, c'est ce que mon action save ressemble:
[HttpPost]
public RedirectToRouteResult SaveSingleEdit(CompLang newcomplang)
{
var oldCompLang = _db.CompLangs.First(x => x.Id == newcomplang.Id);
_db.CompLangs.Attach(oldCompLang);
newcomplang.LastUpdate = DateTime.Today;
_db.CompLangs.ApplyCurrentValues(newcomplang);
_db.SaveChanges();
var comp = _db.CompLangs.First(x => x.Id == newcomplang.Id);
return RedirectToAction("ViewSingleEdit", comp);
}
J'ai trouvé que je pouvais l'utiliser pour itérer sur ma propriété de oldCompLang:
var oldpropertyInfos = oldCompLang.GetType().GetProperties();
Mais ce n'est pas vraiment utile, car il ne me montre les propriétés (Id, Nom, Statut...) et non pas les valeurs de ces propriétés (1, Bonjour, Prêts...).
Je pouvais juste aller à la dure:
if (oldCompLang.Status != newcomplang.Status)
{
//Add to my activity log table something for this scenario
}
Mais je ne veux vraiment pas être fait pour que toutes les propriétés de l'objet.
Je ne sais pas quel est le meilleur moyen de parcourir à la fois des objets à trouver des décalages (par exemple l'utilisateur a changé le nom, ou l'état...) et de construire une liste de ces différences que je peux stocker dans une autre table.
Vous devez vous connecter pour publier un commentaire.
Il n'est pas mauvais en soit, vous pouvez comparer les propriétés "à la main" à l'aide de réflexion et d'écrire une extension des méthodes de réutilisation - vous pouvez prendre cela comme un point de départ:
if (selfValue is DateTime && toValue is DateTime) { DateTime from = (DateTime)selfValue; DateTime to = (DateTime)toValue; if (!DateTime.Equals(from, to)) { }
Si vous utilisez EntityFramework, vous pouvez obtenir des changements directement à partir de la ObjectContext
Obtenir le changement d'état des entrées:
Sauvés des noms de propriété et d'origine et les valeurs modifiées:
C'est mieux que @BrokenGlass de répondre parce que cela va aller en profondeur dans le graphe d'objets pour tout a changé etats et vous donnera les modifications des propriétés des associés collections. Il est également préférable parce qu'elle reflète tout le ObjectContext sauvegarde de la base de données. Avec la solution retenue, vous pouvez obtenir des modifications de la propriété qui ne sera pas réellement être conservées dans la situation où vous êtes déconnecté via le contexte de l'objet.
Avec EF 4.0, vous pouvez également remplacer la SaveChanges() la méthode et l'envelopper un audit ou d'activité dans la même transaction que l'éventuelle entité enregistrer sens d'une piste d'audit ne sont pas exister sans l'entité a changé, et vice-versa. Cela garantit un registre précis. Si vous ne pouvez pas garantir un audit précis que son presque inutile.
L'extension de jfar, la réponse à apporter certains éclaircissements et modifications que j'ai eu à faire pour le faire fonctionner:
utiliser cette code personnalisé de comparer 2 objets. Si elles ne parviennent pas l'enregistrer. La conception du point de vue de la Créer cette classe Utilitaire.
l'utiliser comme
object1.IsEqualTo(object2)
Mettre en œuvre
IEquatable<T>
sur votre entité. Une autre façon est de mettre en œuvre personnaliséeIComparer<T>
où vous pouvez par exemple exposer événement qui sera déclenché si la propriété est différente.