简体   繁体   English

使用FindAsync时EF6不跟踪实体上的更改

[英]EF6 not tracking changes on entities when using FindAsync

I'm using EF6, with a Repository pattern (a repository has its own context instance). 我正在使用带有存储库模式的EF6(存储库具有自己的上下文实例)。 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 . 当我使用FindAsync获取和修改实体时,不会跟踪更改,因此在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. 但是,我还通过IQueryable通过存储库公开了该表,并且如果以这种方式获取实体,则所有更改都将正确保存。 I'm trying to figure out why changes are not tracked when I use the FindAsync method. 我试图弄清楚为什么在使用FindAsync方法时未跟踪更改。

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: 用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): 通过公开的IQueryable访问路由(修改后不会保存更改):

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! 我确定我缺少某些东西(对于EF来说有些新意),所以任何帮助将不胜感激,谢谢!

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. 我只是遇到了这个问题-我怀疑这是EF的错误,因为手动更新EntityState并随后强制上下文保存更改,或者在同一Microsoft EntityFramework库中使用同一方法的同步版本不会导致任何问题。

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. 具体来说,当使用Microsoft.AspNet.Identity.EntityFramework库和UserStore / UserManager类时,使用FindAsync检索对象时,Entity Framework无法正确跟踪后续修改。

Ie was getting this error after FindAsync, then trying to update the DB: 即在FindAsync之后出现此错误,然后尝试更新数据库:

Attaching an entity of type ' MyNamespace.MyUser ' failed because another entity of the same type already has the same primary key value. 附加类型为' MyNamespace.MyUser '的实体失败,因为相同类型的另一个实体已经具有相同的主键值。 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: 我失败的UpdateAsync方法如下所示:

    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. 最终,通过跟踪,我发现即使进行了更改,EntityState仍然“未更改”。 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. 我不能100%地确定这是一个错误,但是如果有足够的人对此进行了验证,则应该使用MSFT打开票证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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