【问题标题】:Intercept Deletes in ASP.NET WebAPI - Breeze在 ASP.NET WebAPI 中拦截删除 - Breeze
【发布时间】:2013-08-06 06:38:34
【问题描述】:

我正在使用 BreezeJS 连接到使用 ASP.NET 开发的 OData 端点。我使用 EFContextProvider 来保存更改。

这一切都很好,但现在我不想删除数据,而是将已删除字段设置为 true。如何拦截删除?

谢谢!

问候, 马蒂斯·特伍德

【问题讨论】:

    标签: asp.net asp.net-web-api breeze


    【解决方案1】:

    您需要在 EFContextProvider 实例上使用 BeforeSaveEntities 拦截器将 EntityState 更改为“已修改”并在您的实体上设置已删除标志。例如:

    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;
            }
        }
    }
    

    【讨论】:

    • 客户会知道订单没有被删除,而是被修改了吗?
    • 我已经安装了 NuGet 包 Breeze.WebApi 1.4.0,并且 EntityState 属性是只读的。我已经试过了.. :(
    • 我正在开发一个 SaaS 解决方案,我们(服务提供商)希望保留数据以进行分析。租户不会再次看到他们的数据。 (所以,它仍然是一个功能删除)
    【解决方案2】:

    一旦您将实体标记为删除,您仍然必须调用 SaveChanges 以将其持久化,并且无论您是在修改、删除还是创建新实体,都能够拦截保存调用。

    保存调用拦截在 BeforeSaveEntity 和/或 BeforeSaveEntities 中完成。 (见http://www.breezejs.com/documentation/efcontextprovider

    【讨论】:

    • 我安装了 NuGet 包 Breeze.WebApi 1.4.0,并且 EntityState 属性是只读的。我已经试过了.. :(
    • 您不应该尝试直接更改 EntityState,而应使用 EntityAspect 的 setDeleted()/setModified() 方法。更多信息请访问breezejs.com/sites/all/apidocs/classes/EntityAspect.html
    • sbelini: setDeleted/setModified 在客户端的 BreezeJS 中,我说的是服务器端。
    【解决方案3】:

    EntityInfo.EntityState 无法由您的代码设置...与您观察到的完全一样。我不确定为什么我们决定阻止该选项,但让我们将其视为给定的。这里有一些东西可以尝试。

    您可以从传递给BeforeSaveEntitiessaveMap 中删除EntityInfo(它是Dictionary&lt;Type, List&lt;EntityInfo&gt;&gt;);这应该会阻止 Breeze 尝试保存删除实体请求。

    现在向字典中添加一个新的EntityInfo,这次EntityInfoEntityState 处于修改状态。以下三行应该可以解决问题:

    var newInfo = context.CreateEntityInfo(revisedEntity, EntityState.Modified); newInfo.OriginalValuesMap['Deleted']=true; // 所以 Context 会持续改变这个属性 saveMap[revisedEntity.getType()].add(newInfo);

    这个我没试过;我正在这里用 SO 编写代码,所以它甚至可能无法编译。但你明白了。

    警告 ContextProvider 有可能将此实体发送回 Breeze 客户端,就好像它已被真正修改过一样;这可能会混淆微风,它可能会将其保持在未修改状态的缓存中,就像在保存修改后的实体之后一样。请对此进行测试。如果发生这种情况,您可以在保存成功回调中添加一些额外的逻辑,以从缓存中删除该实体(将其置于 Detached 状态)。

    2013 年 8 月 5 日更新

    我接受你的挑战。请解释为什么当我在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

    【讨论】:

    • 沃德您好,感谢您的信息!除了 OriginalValuesMap 为空,并且是只读的..
    猜你喜欢
    • 2018-11-14
    • 1970-01-01
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    相关资源
    最近更新 更多