0

public override saveChanges(){
    var changeList = tracker.detectChange();
    foreach(var change in changeList){
        switch(change.state){
            case ADD: ...
            case MODIFIED: ...
        }
    }
      
      
    base.saveChanges();
}

I have the above code structure (only pseudo code for illustrating idea) of creating audit trail when save changes.

The only problem is that, I cannot get the newly added record ID as saveChanges has not yet been called, however if I call saveChanges ahead, then the tracker could not track the changes as ALL state of the entries will become unchanged!

So how can I still track the changes while getting the new record ID ?

EDITED

Reason why I have to get the new record ID, as you may guess, is to save an audit trail record in DB. For some reason, it has to be an XML document which stores the entity's ID, original value & new value (and some other stuff which is out of concern).

Say for a newly added "Item" in Item table in DB, I have to store a new audit trail record which at least showing this new "Item" 's ID, original value (which is null), and new value.

shole
  • 4,046
  • 2
  • 29
  • 69
  • Can you explain what are you trying to achieve with the new record Id? – wonderbell Apr 05 '16 at 09:21
  • Do you use `EntityFramework`? – StepUp Apr 05 '16 at 09:23
  • @wonderbell Please see edited. – shole Apr 05 '16 at 09:27
  • You can save the entities added / modified / deleted in separate list inside your `for loop`. After `saveChanges` is called, all entities would be updated with new Ids. You can use your lists then to create the desired XML. – wonderbell Apr 05 '16 at 09:31
  • @wonderbell That's what I am trying to do, but it becomes another problem: how to deep copy an DbEntityEntry object(s). As after you call savechanges, all these objects will become "unchanged" state, you cannot determine which is added /modified/ deleted if you do not deep copy ahead – shole Apr 05 '16 at 09:35
  • @StepUp Yes, I am using EntityFramework 6 – shole Apr 05 '16 at 09:36
  • please, show your model classes what is the relationship? `One-to-Many`? – StepUp Apr 05 '16 at 09:39
  • @StepUp How come it is related to model classes? It is savechange() in general context level, for all model classes. Yea there are all kinds of relationship(1-* , 1-1, * - *) but I do not think that is related... – shole Apr 05 '16 at 09:44
  • 1
    @StepUp Thanks for advice, I will try to clarify the question once I get home – shole Apr 05 '16 at 09:55
  • At first you clarify your question and you'll get more help. At second, when you have One-to-Many, then you should say to `EntityFramework` what you want with newly attached collections. http://stackoverflow.com/questions/5538974/the-relationship-could-not-be-changed-because-one-or-more-of-the-foreign-key-pro – StepUp Apr 05 '16 at 09:59

1 Answers1

3

The changed entities can be added to separate lists according to their state before the method saveChanges is called.

After saveChanges all entities would be updated with new Ids and the corresponding lists can be used to generate the audit logs.

public override saveChanges(){
    // gather audit data
    initialize List<Entity> addedEntities, modifiedEntities, deletedEntities
    var changeList = tracker.detectChange();
    foreach(var change in changeList){
        switch(change.state){
            case ADD: add to addedEntities
            case MODIFIED: add to modifiedEntities
        }
    }


    base.saveChanges();
    performAudit(addedEntities, modifiedEntities, deletedEntities);
}

function performAudit(...){
  generateXML(...);
  saveToDB(...);
  sendEmail(...);
}

Note: I have not tested if deletedEntities would still be valid, but they can anyway be audited before saveChanges as they already have an Id. But I hope you get an idea on how to solve your problem.

wonderbell
  • 1,126
  • 9
  • 19