我正在创建一个通信应用程序(使用 .net core 1.1 mvc 和 signalr/knockout ),并且我有以下 pocos:
房间 用户 邮政 修改后
posts 是 postRevision 的容器,为了方便起见,它引用了最新版本
其他一切都如你所想象的那样。我显然省略了很多细节。
我的用户有头像属性。 当我更新用户的头像时,我会删除他们的旧头像,然后更新为新头像。然后,在房间中,所述用户的帖子(实际上是帖子修订版)不再有友好的头像,现在他们有一个损坏的图像图标。我仍在开发中,因此在多用户场景中不会发生这种情况。这只是我从更改头像的 mvc Controller 跳转到显示帖子的 signalr/knockout 页面。
当我停止并运行服务器时,图像已修复。 看起来 Entity Framework 正在缓存结果而不是更新。
在我的 Controller 中我有这个代码片段:
user.Avatar = imageId.ToString();
_context.Entry(user).State = EntityState.Modified;
await _context.SaveChangesAsync();
_context.Entry(user).State = EntityState.Detached;
return new JsonResult(new { status = "sucess" });
在我的中心,我有这个片段用于获取帖子页面:
data = await _context.Posts
.Include(x=> x.LatestRevision)
.Include(x => x.LatestRevision.Blob)
.Include(x => x.LatestRevision.Creator)
.Where(x=> x.Room.Id == roomId
&& x.Id < currentPostId)
.OrderByDescending(x => x.Id)
.Take(_roomPageSize).ToListAsync();
我不确定如何告诉信号器上下文进行更新,特别是因为该页面未打开,并且理论上该页面超出了范围,因此甚至还没有创建上下文。 这是我的 Startup.cs 的相关部分
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>();
最佳答案
问题在于每个上下文的缓存系统实际上没有相互传达它们的更改。
我知道用旧数据显示的确切用户对象,我调用了
_context.Entry(user).State = EntityState.Detached;
在中心运行我的查询之前。这什么也没做。旧数据仍在显示。 (在实际使用中,这不会那么简单,但我现在是系统中唯一的用户)
最终的工作是将这一行添加到我在中心的查询中:
.AsNoTracking()
这意味着我丢失了所有缓存,并且由于 99% 的更改将正确地流经集线器上下文,这似乎很遗憾,但它现在正在工作。
我想知道是否不应该更改在 MVC 端保存对象的方式,以便我的操作使用集线器上下文,这样它始终处于循环中。 我必须在 MVC 端的几个位置添加 .AsNoTracking(),但这是放置它的更好位置。
这里有一篇关于如何做到这一点的文章: SignalR + posting a message to a Hub via an action method
-edit:上面的链接仅用于调用客户端方法。目前还没有调用服务器端集线器代码的好方法。请参阅Use Hub methods from controller?
关于entity-framework - EntityFramework 正在缓存旧的过时数据,我不知道如何阻止它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41906325/