简体   繁体   中英

EF6 not tracking changes on entities when using FindAsync

I'm using EF6, with a Repository pattern (a repository has its own context instance). When I use FindAsync to obtain and modify an entity, the changes are not tracked, and so any properties that are edited are not saved upon SaveChanges . However, I also expose the table through the repository via IQueryable , and if I obtain an entity that way, all changes are saved properly. I'm trying to figure out why changes are not tracked when I use the FindAsync method.

My Find repo method:

public async Task<CDCRoute> FindDrivingRouteAsync(long routeId, string userId)
        {
            var route = await routeContext.Routes.FindAsync(routeId);
            if (route != null && route.CDCUserInfoId == userId)
            {
                return route;
            }

            return null;
        }

Table exposed with IQueryable:

public IQueryable<CDCRoute> Routes
        {
            get { return routeContext.Routes; }
        }

Accessing a route via Find (does not save changes when modified):

routeRepo.FindDrivingRouteAsync(message.RouteId, message.UserId);

Accessing a route via the exposed IQueryable (does save changes when modified):

routeRepo.Routes.FirstOrDefault(r => r.RouteId == message.RouteId && r.CDCUserInfoId == message.UserId);

I'm sure I am missing something (am somewhat new to EF), so any help would be greatly appreciated, thanks!

I just had this problem - I suspect it's a bug with EF, since manually updating the EntityState & then forcing the context to save changes, or using the Synchronous version of the same method in the same Microsoft EntityFramework library, caused no issues.

Specifically, when using the Microsoft.AspNet.Identity.EntityFramework library & UserStore/UserManager classes, when an object was retrieved using FindAsync, subsequent modifications were not properly tracked by Entity Framework.

Ie was getting this error after FindAsync, then trying to update the DB:

Attaching an entity of type ' MyNamespace.MyUser ' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

My UpdateAsync method that was failing looked like this:

    public async Task UpdateAsync(MyUser user)
    {
        var result =  await _manager.UpdateAsync(user); //State = EntityState.Unchanged
        //UpdateAsync above is directly inherited from Microsoft.AspNet.Identity.EntityFramework.UserManager<T>
        //ERROR! Primary key duplicate (Default identity method doing Attach :/ )
    }

Eventually through tracking I found that the EntityState was still "Unchanged" even though changes were made. I then changed the code to this:

    public async Task UpdateAsync(MyUser user)
    {
        _store.Context.Entry(user).State = EntityState.Modified;
        var result = await _store.Context.SaveChangesAsync();
        //var result =  await _manager.UpdateAsync(user);
    }

..the changes were then picked up & auto-magically updated in the DB. A completely synchronous Find & Update (using the same library) also allowed the Entity to be tracked & updated - this solution I deemed less acceptable than a workaround.

I'm not 100% certain it's a bug, but if this is verified by enough people, someone should open a ticket with MSFT.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM