Breeze:从另一个用户中删除从数据库中删除的缓存中的实体而不清除整个缓存?

时间:2013-11-23 13:47:25

标签: caching breeze

我面临的问题可能很常见,但我找不到任何解决方案。 当用户在其客户端上的缓存中有实体而另一个用户删除其中一些实体(在服务器上)时,会发生此问题。当第一个用户想要更新其数据时,不会从缓存中删除已删除的实体。您可以通过每次更新时清除缓存来解决此问题,但之后您也会丢失所有未保存的更改。 我错过了一些明显的东西吗?

示例:

型号:

public class Order
{
    [Key]
    public int Id { get; set; }
    public ICollection<OrderDetail> OrderDetails { get; set; }
}

public class OrderDetail
{
    [Key]
    public int Id { get; set; }
    [ForeignKey("Order")]
    public int Order_Id { get; set; }
    public virtual Order Order { get; set; }
}

客户代码:

function getOrder(orderId, orderObservable) {
    var query = EntityQuery.from("Orders")
                .where("orderId", "==", orderId)
                .expand("orderDetails");
    return manager.executeQuery(query).then(querySucceeded).fail(queryFailed);

    function querySucceeded(data) {             
        var order = data.results[0]; 
        // NOTE: the removed orderdetail is still there 'order.orderDetails'
        orderObservable(order);
    } 
}

分步方案:

  1. 用户A查询订单及其相应的订单详细信息。
  2. 然后将订单和订单详细信息放入缓存中。
  3. 用户B删除orderdetail并将更改保存到服务器。
  4. 用户A查询以获取订单的最新更新。
  5. 当查询返回时,删除的orderdetail仍然存在。
  6. 在breeze-docs中,标题为“关于缓存清除的重要注意事项”,有一种解决方案可以通过比较缓存和查询结果来删除缓存的实体,并分离结果中缺少的实体。 http://www.breezejs.com/documentation/entitymanager-and-caching 但在这种情况下,这不起作用。我猜这与orderdetails与订单有关并且在将其传递给成功回调之前从缓存中“拾取”这一事实有关。

    感谢所有帮助!

1 个答案:

答案 0 :(得分:3)

你面临的问题不是Breeze,而是一般的设计。我想到了几个选项 -

  1. 使用SignalR通知您的Web应用程序已发生更改,从缓存中分离任何已删除的实体。

  2. 使用已归档或已删除的标志,而不是从数据库中删除实体。

  3. 两者各有利弊。

    使用SignalR,您需要使管道工作到位以进行通知,并围绕删除已删除的实体设置特定的工作流程

    manager.detachEntity(entityToDetach);
    

    您要分离而不是删除的原因是因为如果将其设置为已删除,那么您的Breeze实体管理器仍然认为您需要将该更改保留到数据库中。

    如果你使用一个标志,那么你可以简单地设置你的业务逻辑来忽略被标记为已删除或存档的实体,当你查询数据库时,它会将更改返回给该实体并停止显示

    myEntity().archived(true);
    

    这里的问题是,如果您的实体与您的查询不匹配,它将永远不会返回更新的实体,让客户知道它已存档或删除。另一个警告是,您将在数据库中放置不再处于活动状态的信息。

    根据您的应用程序和要求类型,您应该选择其中一种,或者提出另一种选择。希望有所帮助。