breeze 实体被意外缓存
breeze entities get cached unwantedly
我遇到了 breeze 实体及其导航属性的问题,这些属性是通过 WebAPI 调用填充的。
return EntityQuery.from('UserInfo')
.withParameters({ clientId: clientId, userId: userId })
.using(self.manager)
.execute()
.then(querySucceeded, this._queryFailed);
function querySucceeded(data) {
return data.results[0];
}
这是事件发生的顺序。
- 调用 'UserInfo' API 调用并在页面上显示用户信息。
- 对 data.user.userWorkLocations1 进行修改(我将 UserWorkLocation object 添加到 collection,因此现在它有 3 个用户工作位置)并保存。
- 转到另一个页面并执行一些 CRUD 操作,从该用户的 WorkLocation 列表中删除一个 UserWorkLocation。
- 我确保在数据库中并验证此用户只有两个用户工作位置。
- 再次调用 'UserInfo' API 调用并在页面上显示用户信息。
问题是 - 在第二个 UserInfo API 调用中,在 breeze 查询端,我可以看到 3 个 userWorkLocation object(见屏幕截图)。
但我检查了开发者工具上的响应,响应中只有两个 userWorkLocation object(见屏幕截图)。
.
这是在#3 中删除 userworklocation 的服务器端代码。
if (activeStatus != location.ActiveStatus && location.ActiveStatus == 0)
{
// 删除所有工作地点分配<br>
ClientContext.UserWorkLocations.RemoveRange(ClientContext.UserWorkLocations.Where(u => u.FkLocationId == location.LocationId));<br>
}
ClientContext.SaveChanges();
我在服务器端调用下了一个断点,也确保了它returns两个。我不明白breeze怎么读到collection里的3个object,多出来的一个是我删掉的。可能缓存?我该如何解决?
Breeze 的 正常 流程是删除发生在客户端并与服务器通信。这里的问题是 Breeze 不知道服务器上发生的删除。这是一个经典的 缓存一致性 问题。
基本上可以通过三种方法解决这个问题:
清除您怀疑已被删除的实体或实体类型的缓存,然后重新查询它们。 Keeping a fresh cache.
中对这种方法进行了深入讨论
使用软删除,其中每个实体都有一个标志(在代码和数据库中)表示删除。实体并没有真正被删除,它们被标记以便客户端不显示它们。如果在服务器上删除了一个实体,则当客户端下次查询该实体时,"deleted" 标志将为真。
从服务器传达删除。在保存期间,saveResult, an example of which is in the Saving Changes 页面的 deletedKeys
属性 有助于实现这一点。 Breeze EntityManager 自动使用 deletedKeys
删除缓存中的实体。在保存之外,您需要在客户端和服务器之间进行一些其他通信以通知客户端有关删除的信息,例如 SignalR。
每种方法都有其挑战,因此您需要选择最适合您应用的方法。
我遇到了 breeze 实体及其导航属性的问题,这些属性是通过 WebAPI 调用填充的。
return EntityQuery.from('UserInfo')
.withParameters({ clientId: clientId, userId: userId })
.using(self.manager)
.execute()
.then(querySucceeded, this._queryFailed);
function querySucceeded(data) {
return data.results[0];
}
这是事件发生的顺序。
- 调用 'UserInfo' API 调用并在页面上显示用户信息。
- 对 data.user.userWorkLocations1 进行修改(我将 UserWorkLocation object 添加到 collection,因此现在它有 3 个用户工作位置)并保存。
- 转到另一个页面并执行一些 CRUD 操作,从该用户的 WorkLocation 列表中删除一个 UserWorkLocation。
- 我确保在数据库中并验证此用户只有两个用户工作位置。
- 再次调用 'UserInfo' API 调用并在页面上显示用户信息。
问题是 - 在第二个 UserInfo API 调用中,在 breeze 查询端,我可以看到 3 个 userWorkLocation object(见屏幕截图)。
但我检查了开发者工具上的响应,响应中只有两个 userWorkLocation object(见屏幕截图)。
这是在#3 中删除 userworklocation 的服务器端代码。
if (activeStatus != location.ActiveStatus && location.ActiveStatus == 0)
{
// 删除所有工作地点分配<br>
ClientContext.UserWorkLocations.RemoveRange(ClientContext.UserWorkLocations.Where(u => u.FkLocationId == location.LocationId));<br>
}
ClientContext.SaveChanges();
我在服务器端调用下了一个断点,也确保了它returns两个。我不明白breeze怎么读到collection里的3个object,多出来的一个是我删掉的。可能缓存?我该如何解决?
Breeze 的 正常 流程是删除发生在客户端并与服务器通信。这里的问题是 Breeze 不知道服务器上发生的删除。这是一个经典的 缓存一致性 问题。
基本上可以通过三种方法解决这个问题:
清除您怀疑已被删除的实体或实体类型的缓存,然后重新查询它们。 Keeping a fresh cache.
中对这种方法进行了深入讨论
使用软删除,其中每个实体都有一个标志(在代码和数据库中)表示删除。实体并没有真正被删除,它们被标记以便客户端不显示它们。如果在服务器上删除了一个实体,则当客户端下次查询该实体时,"deleted" 标志将为真。
从服务器传达删除。在保存期间,saveResult, an example of which is in the Saving Changes 页面的
deletedKeys
属性 有助于实现这一点。 Breeze EntityManager 自动使用deletedKeys
删除缓存中的实体。在保存之外,您需要在客户端和服务器之间进行一些其他通信以通知客户端有关删除的信息,例如 SignalR。
每种方法都有其挑战,因此您需要选择最适合您应用的方法。