Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity framework change tracking after calling ToList()

I am struggling to understand something with change tracking in EF6.

I have code similar to this.

public class SomeClass
{
    private List<User> _users;
    private DAL _dal;

    public void ProcessUsers()
    {
        _users = _dal.GetUsers();

        foreach(var u in users)
        {
            u.user.Comment = "This is a test";
        }

        _dal.SaveChanges();
    }
}

The DAL class looks a little like this.

public class DAL
{
    ...
    private DataContext _context; // Assume that this is being newed up in a constructor.

    public List GetUsers()
    {
        return _context.Users.ToList();
    }

    public void SaveChanges()
    {
        _context.SaveChanges();
    }
}

So as we can see from the code in the ProcessUsers method we have a list of users and we are modifying that list.

Now I know that this works, Its the way I have always done it however I was always under the impression that the objects in the List (Users in this case) were a reference back to the corresponding object in the DBSet Local collection.

After a bit of thought I am not sure that this is the case as if the context is disposed the list is still populated and can be manipulated (We just loose the ability to push it back to the database without some additional work) so from that perspective the items in the list must be copies of the items from the DBSet Local collection... but if that is the case I wouldn't have though that manipulating an object in the list would have any effect on the object in the dbset as it would be a copy.

In Summary

The question is what happens when I call ToList on a DBSet and how does change tracking work in this instance? - I know it does work, but I think my current understanding might be incorrect.

like image 798
D3vy Avatar asked Jan 11 '17 11:01

D3vy


People also ask

What is ToList () in Entity Framework?

The ToList method allows us to obtain a list of elements of a database using Entity Framework. We could say that it is the default method that people use to bring collections of records. This is due to the powerful amount of methods that lists offer us.

How do I track changes in Entity Framework?

In Entity Framework, change tracking is enabled by default. You can also disable change tracking by setting the AutoDetectChangesEnabled property of DbContext to false. If this property is set to true then the Entity Framework maintains the state of entities.

How does EF core detect changes?

By default, EF Core creates a snapshot of every entity's property values when it is first tracked by a DbContext instance. The values stored in this snapshot are then compared against the current values of the entity in order to determine which property values have changed.

What does EF's DbContext need to be tracking in order to delete a row from the database?

The approach that you adopt to deleting entities via the DbContext depends on whether the context is currently tracking the entity being deleted or not. In the following example, the entity to be deleted is obtained by the context, so the context begins tracking it immediately.


1 Answers

EF has a collection where all the pending changes are tracked (_context.ObjectStateManager, see here...). Further more loading entities with EF you get a proxy instance instead of your real entity-class. Using this proxy EF is "injecting" code into your entity instances which updates change tracking information.

When you dispose your context you loose this information. To add the existing entity instance to another context you can use the _context.Attach() method.

The SaveChanges() does process the _context.ObjectStateManager information.

like image 127
Marc Avatar answered Oct 07 '22 20:10

Marc