The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked

前端 未结 10 1173
一向
一向 2020-11-29 20:11

I have a Service Object Update

public bool Update(object original, object modified)
{
    var originalClient = (Client)original;
    var modifi         


        
10条回答
  •  夕颜
    夕颜 (楼主)
    2020-11-29 21:08

    It sounds as you really just want to track the changes made to the model, not to actually keep an untracked model in memory. May I suggest an alternative approach wich will remove the problem entirely?

    EF will automticallly track changes for you. How about making use of that built in logic?

    Ovverride SaveChanges() in your DbContext.

        public override int SaveChanges()
        {
            foreach (var entry in ChangeTracker.Entries())
            {
                if (entry.State == EntityState.Modified)
                {
                    // Get the changed values.
                    var modifiedProps = ObjectStateManager.GetObjectStateEntry(entry.EntityKey).GetModifiedProperties();
                    var currentValues = ObjectStateManager.GetObjectStateEntry(entry.EntityKey).CurrentValues;
                    foreach (var propName in modifiedProps)
                    {
                        var newValue = currentValues[propName];
                        //log changes
                    }
                }
            }
    
            return base.SaveChanges();
        }
    

    Good examples can be found here:

    Entity Framework 6: audit/track changes

    Implementing Audit Log / Change History with MVC & Entity Framework

    EDIT: Client can easily be changed to an interface. Let's say ITrackableEntity. This way you can centralize the logic and automatically log all changes to all entities that implement a specific interface. The interface itself doesn't have any specific properties.

        public override int SaveChanges()
        {
            foreach (var entry in ChangeTracker.Entries())
            {
                if (entry.State == EntityState.Modified)
                {
                    // Same code as example above.
                }
            }
    
            return base.SaveChanges();
        }
    

    Also, take a look at eranga's great suggestion to subscribe instead of actually overriding SaveChanges().

提交回复
热议问题