2

I have been working with ASP.NET Core to build the API and for data access I am using EF Core. Surfing around Stackoverflow and Google, I can't find a way to update only modified columns with the repository pattern.

Is there any way to check whether values have changed or not?

public virtual void Update(T entity)
{
       // DbContext.Attach(entity);
        var dbEntityEntry = DbContext.Entry(entity);

        foreach (var property in dbEntityEntry.Properties)
        {
            var original = dbEntityEntry.OriginalValues.GetValue<object>(property.Metadata.Name);
            var current = dbEntityEntry.CurrentValues.GetValue<object>(property.Metadata.Name);

            if (original != null && !original.Equals(current))
                dbEntityEntry.Property(property.Metadata.Name).IsModified = true;
        }
}

I tried to implement like EF 6 but it is throwing an InvalidCastException

System.InvalidCastException: 'Unable to cast object of type System.Func'2[Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry,System.Int32]' to type 'System.Func`2[Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry,System.Object]'.'

I am directly updating object as received from client to in action controller and updating it.

Any help would be really appreciated.

Thanks

3
  • Why do you think you'll have to do that yourself? Did you capture an UPDATE query in a profiler and notice all fields were present in the SET clause, even the unchanged ones? Commented Jul 26, 2017 at 20:15
  • Yes I have checked with Sql Express Profiler , when sending the whole object , even if they have unchanged values , they are set in UPDATE statement. If I don't send the properties in json object , it throws ValidationEntityResult. Commented Jul 27, 2017 at 6:45
  • Has anyone faced this issue ? Commented Jul 30, 2017 at 13:25

1 Answer 1

2

If the original T Entity that your passing in is not originally retrieved from the dbContext then the entity wont be tracked, so EF itself wont be able to track what properties have changed or not.

Also calling dbContext.Update marks all properties on an entity as dirty either way.

The best suggestion would be to first fetch the entity from the DBContext, then use something like automapper to map the properties of the passed in entity to your retrieved model, then call DbContext.SaveChanges() this will then only update properties that have changed during the map. Automapper will take care of only mapping properties that exist on both sides, and you can configure the mapping if you need more fine grained control.

Psuedo code below:

public virtual void Update(T entity)
{
       var existingEntity = DbContext.Entity.First(x => x.Id == entity.Id);
       autoMapper.Map(entity, existingEntity);
       DbContext.SaveChanges();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.