none
How to get a list of the fields that were changed during a EDIT action call? RRS feed

  • Question

  • Hi all,

    Trying to adapt to EF and use less SQL procs but it's been daunting. In our SQL procs, every time a user change a specific field, we add an entry in a History table containing the NAME of the field as well as the OLD and the NEW value of the field.

    Based on the code below (basic CRUD code) I am trying to obtain a list of fields that were changed and then add them to my History table. Here is my code:

            public void InsertOrUpdate(Component component)
            {
                if (component.component_id == default(int))
                {
                    // New entity
                    component.created = DateTime.UtcNow;
                    component.created_by = "John";
                    context.Components.Add(component);
                }
                else
                {
                    // Existing entity
                    component.modified = DateTime.UtcNow;
                    component.modified_by = "John";
                    context.Entry(component).State = EntityState.Modified;
    
                    //need to compare the values in component with the ones in the database; see which ones are different and log then into a History table
                }
            }
    

    If there is no way to obtain a collection of these fields, it seems to me that I rather stick to our SQL procs which do all the job for me.

    Any ideas?


    Max
    Friday, October 7, 2011 7:14 PM

Answers

All replies

  • Hi Max,

    I know you can get a list of properties that are modified using the ObjectStateEntry class and get an enumeration of the changed properties.  So maybe somethng like this would work:

    public void InsertOrUpdate(Component component)
            {
                if (component.component_id == default(int))
                {
                    // New entity
                    component.created = DateTime.UtcNow;
                    component.created_by = "John";
                    context.Components.Add(component);
                }
                else
                {
                    // Existing entity
    
    
                    ObjectStateEntry stateEntry = context.ObjectStateManager
            .GetObjectStateEntry(((IEntityWithKey)component).EntityKey);
    
    
                    component.modified = DateTime.UtcNow;
                    component.modified_by = "John";
                    context.Entry(component).State = EntityState.Modified;
    
     foreach (string propName in stateEntry.GetModifiedProperties()) 
    
                    { 
    
                         string PropertyName = propName;
                         string OrigValue = stateEntry.OriginalValues[propName]; 
                     
                            string NewValue = stateEntry.CurrentValues[propName]; 
    
                       DoLogRoutine(OrigValue, NewValue, propName, "component");
    
    }
    
             
    
                  }
            }
    
    
    

     

     

     


    Tom Overton
    Friday, October 7, 2011 8:02 PM
  • Hi,

    I am writing to check the status of the issue on your side. Would you mind letting us know the result of the suggestions?

    If you need further assistance, please feel free to let me know. I will be more than happy to be of assistance.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, October 14, 2011 1:37 AM
    Moderator
  • Sorry for the delay... I am using DbContext so I think that is the reason I dont have context.ObjectStateManager???

    Error 1 'App1.Models.CustomContext' does not contain a definition for 'ObjectStateManager' and no extension method 'ObjectStateManager' accepting a first argument of type 'App1.Models.CustomContext' could be found (are you missing a using directive or an assembly reference?)

    // Existing entity
                    System.Data.Objects.ObjectStateEntry stateEntry = context.ObjectStateManager.GetObjectStateEntry(((IEntityWithKey)component).EntityKey);
    

    Thanks

     


    Max
    Monday, October 17, 2011 8:40 PM
  • Hi Max,

    Thanks for your feedback.

    using (var context = new UnicornsContext())
    {
        // Create an entity that is not being tracked
        var unicorn = new Unicorn { Name = "Franky" };
    
        // Read and set the current value of Name as before
        var currentName1 = context.Entry(unicorn).Property(u => u.Name).CurrentValue;
        context.Entry(unicorn).Property(u => u.Name).CurrentValue = "Franky";
        var currentName2 = context.Entry(unicorn).Property("Name").CurrentValue;
        context.Entry(unicorn).Property("Name").CurrentValue = "Squeaky";
    }
    

    You can use CurrentValue by context.Entry(), the more information is here : http://blogs.msdn.com/b/adonet/archive/2011/01/30/using-dbcontext-in-ef-feature-ctp5-part-5-working-with-property-values.aspx

    Hope it helps.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked as answer by Maximusdm Friday, October 21, 2011 2:06 PM
    Tuesday, October 18, 2011 6:09 AM
    Moderator
  • Hi,

    I am writing to check the status of the issue on your side. Would you mind letting us know the result of the suggestions?

    If you need further assistance, please feel free to let me know. I will be more than happy to be of assistance.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, October 20, 2011 9:17 AM
    Moderator