2010-12-07 26 views
2

C'est mon troisième jour et ça me rend fou.Impossible d'auditer sur le cadre d'entité d'insertion. Je suis coincé pouvez-vous aider?

besoin de vérifier chaque fois que je fais je un insert accrochage obviosly à SaveChanges est pas bon pour moi que je besoin du nouveau GeneratedID que vous obtenez lorsque vous ajoutez un nouveau record

J'ai overriden SaveChanges et là, je peux maintenant obtenir les entrées nouvellement ajoutées avec la clé primaire. Mon problème est que j'ai maintenant un nouveau fichier à insérer et que j'ai besoin de rappeler SaveChanges. Soit je me retrouve dans une boucle infinie, soit j'insère deux fois l'enregistrement.

Comment auditer un insert si vous avez besoin de la clé primaire de votre exemple d'objet nouvellement inséré (CustomerId)

public override int SaveChanges(SaveOptions options) 
    { 
    int changes = base.SaveChanges(SaveOptions.DetectChangesBeforeSave); 
    IEnumerable<ObjectStateEntry> entries = Context.ObjectStateManager.GetObjectStateEntries(EntityState.Added); 
    foreach (ObjectStateEntry entry in entries) 
    { 
      var auditLog=CreateAuditLog(Entry); 
    } 

//Because I have saved I now got the new Id. I now need to save the newly created log and therefore 
//I call save again but now this will save again all the previous stuff too or get in a infinite loop 
//Is there a way I could just save the newly added stuff what is the workaround? 

    base.SaveChanges(); 


    return changes; 
    } 

Comment auditer sur insert? un exemple?

+0

pouvez-vous fournir le code pour cette méthode s'il vous plaît -> CreateAuditLog (Entrée); – Rob

+0

Quel moteur de base de données utilisez-vous? –

+0

@Rob Je vais ajouter le code mais j'ai besoin de le retravailler car il y a beaucoup de choses que je ne peux pas inclure. @Raj J'utilise Sql Server 2008 – user9969

Répondre

4

Avez-vous avoir pour le faire dans le code? Pourquoi ne pas utiliser un déclencheur dans la base de données et copier l'enregistrement dans une table d'audit?

Une alternative pourrait être de créer un Dictionary<T,bool> pour contenir les éléments audités.

Une fois que vous avez audité l'élément, définissez la clé (bool) sur true pour indiquer qu'il a été audité.

Ou une autre option consiste à au lieu d'enregistrer l'audit immédiatement, le conserver dans un autre magasin (en mémoire, cache, session, etc). Ensuite, en fonction du type d'application que vous utilisez, vous pouvez valider ces éléments audités dans la base de données à la fin de la "demande".

Je ne fais que lancer des idées ici - mais je crois toujours qu'un déclencheur serait la chose la plus simple/la plus sûre à faire ici.

+2

+1, les triggers seraient tellement plus simples ...la seule raison pour laquelle je peux penser à ne pas utiliser les déclencheurs est si la base de données cible ne les supporte pas, mais je ne connais pas d'exemples concrets. Je voudrais pouvoir donner un autre upvote ici :-) –

+0

Merci pour votre réponse.J'essaierai de mettre en œuvre vos options.let vous savez – user9969

+1

Merci @adrift. Le fait que le PO effectue cette vérification si tard (par exemple, SavingChanges) me dit qu'il s'agit d'une vérification d'enregistrement, et non d'un audit «basé sur le comportement» - sinon, cela pourrait être fait plus tôt. Ces types de choses sont un cas d'utilisation parfait pour les déclencheurs. J'utilise moi-même des déclencheurs pour les tables d'audit. – RPM1984

0

Je ne sais pas à quoi ressemble votre journal d'audit, mais s'il contient une référence à Entry, ne pouvez-vous pas CreateAuditLog (Entry) avant d'appeler base.SaveChanges(), et les ID devraient tous fonctionner.

+0

J'ai créé l'auditLog avant, mais il ne savait pas à propos du generateId que je devais enregistrer par exemple "CustomerId" .So je ne pourrais jamais enregistrer sa clé primaire – user9969

0

Je pense que vous pourriez vouloir essayer quelque chose d'un peu différent:

Créer une autre classe qui gère l'enregistrement de vos modifications et enregistrer votre journal d'audit comme ce qui suit (penser c'est une sorte de code pseudo - il n » t complet, mais devrait donner une idée u):

public void Save(Context context) 
{ 
    using (Transaction scope = new TransactionScope) 
    { 

    context.SaveChanges(SaveOptions.DetectChangesBeforeSave); 

    auditContext = new MyAuditContext(); 
    var auditLog=CreateAuditLog(Entry); 

    myAudtContext.SaveChanges(SaveOptions.DetectChangesBeforeSave); 

    scope.Complete(); 

    context.AcceptChanges(); 

    myAuditContext.AcceptChanges() 
} 

}

+0

@ Pedro.I va mettre quelque chose ensemble. Je n'ai pas essayé TransactionScope.Sould I override SaveChanges encore? – user9969

+0

Je pense que vous n'avez pas besoin de surcharger SaveChanges. – Pedro

+0

J'ai utilisé une solution similaire, et j'ai remplacé SaveChanges afin que je puisse enregistrer les enregistrements insérés, obtenir leurs ID, puis sauvegarder les enregistrements d'audit (qui étaient dans un cache avec une référence à l'entité insérée). – Darren

0

un peu en retard dans le jeu, mais je suis tombé sur ce poste que j'ai eu le même problème. Appeler la méthode ObjectStateEntry.AcceptChanges a fonctionné pour moi. MSDN article here