我正在使用 BreezeJS 连接到使用 ASP.NET 开发的 OData 端点。我使用 EFContextProvider 来保存更改。
这一切都很好,但现在我不想删除数据,而是将已删除字段设置为 true。如何拦截删除?
谢谢!
问候, Matthijs ter Wood
我正在使用 BreezeJS 连接到使用 ASP.NET 开发的 OData 端点。我使用 EFContextProvider 来保存更改。
这一切都很好,但现在我不想删除数据,而是将已删除字段设置为 true。如何拦截删除?
谢谢!
问候, Matthijs ter Wood
您需要在 EFContextProvider 实例上使用BeforeSaveEntities拦截器将其更改EntityState
为“Modified”并在您的实体上设置 Deleted 标志。例如:
protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap)
{
var orderInfos = saveMap[typeof(Order)];
foreach (var info in orderInfos)
{
var order = (Order)info.Entity;
if (info.EntityState == EntityState.Deleted)
{
order.Deleted = true;
info.EntityState = EntityState.Modified;
}
}
}
您的EntityInfo.EntityState
代码无法设置...与您观察到的完全一样。我不确定为什么我们决定阻止该选项,但让我们将其视为给定的。这里有一些东西可以尝试。
您可以EntityInfo
从saveMap
传入的BeforeSaveEntities
(its a Dictionary<Type, List<EntityInfo>>
) 中删除一个;这应该会阻止 Breeze 尝试保存删除实体请求。
现在在字典中添加一个新EntityInfo
的,这次EntityState
是EntityInfo
处于修改状态的 。以下三行应该可以解决问题:
var newInfo = context.CreateEntityInfo(revisedEntity, EntityState.Modified); newInfo.OriginalValuesMap['Deleted']=true; // 所以 Context 会持续改变这个属性 saveMap[revisedEntity.getType()].add(newInfo);
我没有试过这个;我正在这里用 SO 编写代码,所以它甚至可能无法编译。但你明白了。
警告有可能ContextProvider
会将该实体发送回 Breeze 客户端,就好像它已被真正修改过一样;这可能会混淆微风,它可能会将其保持在未修改状态的缓存中,就像在保存修改后的实体之后一样。请对此进行测试。如果发生这种情况,您可以在保存成功回调中添加一些额外的逻辑,以从缓存中删除该实体(将其置于分离状态)。
我接受你的挑战。请解释为什么当我在BeforeSaveEntities
方法的第一行设置断点时,以下代码在我的调试器中有效:-)
saveMap[typeof(Zza.Model.Customer)][0].OriginalValuesMap; // 计数 = 0 saveMap[typeof(Zza.Model.Customer)][0].OriginalValuesMap["Deleted"] = true; saveMap[typeof(Zza.Model.Customer)][0].OriginalValuesMap["Deleted"]; // 真的 saveMap[typeof(Zza.Model.Customer)][0].OriginalValuesMap.Count; // 1
将实体标记为删除后,您仍然必须调用 SaveChanges 以将其持久化,并且无论您是在修改、删除还是创建新实体,都能够拦截保存调用。
保存调用拦截在 BeforeSaveEntity 和/或 BeforeSaveEntities 中完成。(见http://www.breezejs.com/documentation/efcontextprovider)