Entity Framework Core(EF Core) 跟踪 Tracker 缓存刷新问题

一、问题场景

UserA、UserB 分别打开页面、使用 DbContext 在页面中显示相同数据列表。

然后 UserA 在列表中增加一条记录、修改一条记录,使用 DbContext.SaveChangesAsync() 更新数据库。

此时,UserB 刷新数据列表,只会加载 UserA 新增加的记录,而修改的记录不会刷新显示修改结果。

如果 UserB 注销或者关闭浏览器重新打开页面,则会显示所有变化。

二、问题原因分析

EF Core 默认情况下对数据的访问启用了模型跟踪,UserB 刷新列表时不知道 UserA 修改了数据,没有重新查询加载修改结果。

三、解决办法

1. 如果 UserB 只是查询、显示,则查询时可以使用 AsNoTracking() 进行处理。

示例:EditItems = dbContext.Users.AsNoTracking().Where(u => !u.删除).OrderBy(u => u.UserName).ToList();

注:UserA、UserB 通常使用相同的功能页面,都需要查询、修改功能,则此方法不管用。

 

2. 每次查询时,都重新生成一个新的 DbContext,使用新的 DbContext 进行查询,查询后销毁 DbContext。

 

3. 【推荐】增加一个 刷新 按钮,使用 ChangeTracker.Clear() 停止跟踪当前所有实体,然后重新查询数据。

    // 获取 @bind-Items="EditItems" 需要的实体列表
    void GetEditItems()
    {
        /* 停止跟踪当前所有实体:也可以使用查询前,使用新的 DbContext(new DbContext)。
           注:如果使用 AsNoTracking() 方式,则任何修改,在SaveChanges()时,都不会提交到数据库中,
           所以只能用于查询,不能用于其他赋值的操作。*/
        dbContext.ChangeTracker.Clear();
        EditItems = dbContext.Users.Where(u => !u.删除).OrderBy(u => u.UserName).ToList();
        StateHasChanged();
    }

你可能感兴趣的:(EF,Core,#,Blazor,Web,App,数据库,c#,.net,web,app)