1

In a DB-first EF6 application, we have a data access layer which handles all the interaction with EF.

The objects pulled from the context are EF-generated C# classes, these are then mapped to equivalent POCOs in the business layer. This is a common suggested approach as it decouples the layers.

So whilst the application is running, some objects in the business layer get changed (some new ones may be added also, others deleted). When the changes need to be saved to the DB, the objects are mapped back to the business layer. The problem is when EF receives these objects, it has no idea which entities have changed and which haven't.

What's a good way to approach this? (given that hundreds or thousands of objects may or may not have changed)

I've seen other projects solve this by keeping track of changes in lists: NewObjects, UpdatedObjects, DeletedObjects. The obvious problem here is that whenever somethings changes, developers need to remember to update the appropriate list. This ends up with a lot of extra clutter, and it's very easy to make a mistake.

asked Aug 3, 2017 at 12:03
8
  • 1
    EF6 has its own internal change tracking mechanism, so as long as you're willing to always map your business objects back to genuine EF entities (using an EF data context, in a read-update-save cycle), this should never be a problem. Commented Aug 3, 2017 at 16:01
  • But the context is only opened in the DAL when the data is read from the DB, and then closed (else I'd need to hold it open). When the business objects are mapped backed to EF entities later on, I'd need to create a new context, which surely wouldn't have any knowledge of the objects in their original state when loaded? (and not know what has changed) Commented Aug 3, 2017 at 16:07
  • 1
    If you don't have a current context, you have to read the data from the DB immediately before updating it and calling SaveChanges(). Commented Aug 3, 2017 at 16:07
  • Aha I see, and then somehow compare that read data with the EF entities mapped back from the business layer, thank you. Are you aware of an example which demonstrates this comparison? Commented Aug 3, 2017 at 16:10
  • EF performs the comparison. If nothing changes in the EF entity, nothing happens when you call SaveChanges(). Commented Aug 3, 2017 at 16:10

1 Answer 1

2

Entity Framework has its own change tracking mechanisms. Updating an EF entity could be as simple as this (if you're using AutoMapper):

var entity = context.Entities.First(e => e.Id == viewmodel.Id); // fetch the entity
Mapper.Map(viewmodel, entity); // Use automapper to update entity from viewmodel
context.SaveChanges();
answered Aug 3, 2017 at 16:23
4
  • In hindsight - one problem with this approach is that AutoMapper makes new instances of nested objects when mapped - so the context does not acknowledge these nested changes. Should these be added to the context also somehow? Commented Aug 9, 2017 at 9:18
  • Nevermind - I needed to mark each nested object as EntityState.Modified (which seems odd - would EF tracker not be able to tell if something's been modified?) Commented Aug 9, 2017 at 9:51
  • (and looks like this defeats the purpose of the change tracker, it's very slow as it tries to update everything even if just one entity has changed) Commented Aug 9, 2017 at 10:01
  • I had db.Configuration.AutoDetectChangesEnabled = false (embarrasing!) Commented Aug 9, 2017 at 10:44

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.