3

我正在尝试确定使用 BreezeJS 保存的新添加/插入记录的 ID。这样做的目的是广播和通知监听客户端的变化,以便他们可以在必要时更新他们的视图。

BreezeJS 提供了一种有用的方法,通过继承类型化的 EFContextProvider 来拦截对其底层 Data/ObjectContext 的调用。父级公开了几个要覆盖的方法,例如下面的覆盖示例。这适用于更新/删除操作。但是,因为这发生在保存更改之前,因此此时没有为插入生成 ID。我无法在此类中找到可以覆盖的任何其他方法。在最坏的情况下,我将扩展部分数据上下文( ),但我觉得将这个通知系统分成多个类是不合适的。建议?

 protected override bool BeforeSaveEntity(EntityInfo entityInfo) {
        var hubContext = GlobalHost.ConnectionManager.GetHubContext<AppHub>();
        if (entityInfo.EntityState == EntityState.Modified) {
            try {
                hubContext.Clients.All.handleEntityUpdate(new {
                    EntityType = entityInfo.Entity.GetType().Name,
                    Key = ((dynamic)(entityInfo.Entity)).Id
                });
            }
            catch (Exception ep) {
                //failed to notifiy the clients. *Oh well* no biggie.
                //Try, catch, curley, curley, curley.
            }
        }
        else if (entityInfo.EntityState == EntityState.Deleted) {
            try {
                hubContext.Clients.All.handleEntityDelete(new {
                    EntityType = entityInfo.Entity.GetType().Name,
                    Key = ((dynamic)(entityInfo.Entity)).Id
                });
            }
            catch (Exception ep) {
                //failed to notifiy the clients. *Oh well* no biggie.
                //Try, catch, curley, curley, curley.
            }
        }

        return base.BeforeSaveEntity(entityInfo);
    }
4

1 回答 1

3

现在 Breeze 网站上的文档记录很差,但是......我将尝试在这里提供一些至少最少的帮助。关于这个主题的更好的文档正在计划中......现在很快:)

服务器端

Breeze 使您能够通过 IKeyGenerator 接口的实现在服务器上自定义 KeyGeneration(您可以在 Breeze.WebApi 源代码中找到定义的接口以及“备用”NumericKeyGenerator 实现)。

Breeze 将自动发现与您的 EFContextProvider 相同的程序集中此接口的任何自定义实现。仅支持一个实现,但可以编写一个实现来支持您希望为其生成自定义密钥的所有可能的数据类型和属性。如果 Breeze 没有找到它,它将默认使用上面提到的“NumericKeyGenerator”。

客户端

然后,您将需要创建一个客户端“临时”密钥生成器。在以下页面上对此主题进行了一些讨论:here

这个想法是,Breeze 将使用这个“临时”密钥生成器为任何新创建的实体(指定类型)生成临时密钥。保存这些实体后,Breeze 将使用上述服务器端机制生成一个“真实”密钥并将其保存。然后,Breeze 会将 temp -> real 键的映射返回给客户端,并使用此映射自动使用正确的“真实”键更新客户端实体。

您告诉 Breeze 客户端您要通过EntityType.setProperties方法调用自定义密钥生成,如下所示:

var regionType = testFns.metadataStore.getEntityType("Region");
regionType.setProperties({ 
   autoGeneratedKeyType: AutoGeneratedKeyType.KeyGenerator }
); 

请注意,您只是告诉 Breeze 使用自定义密钥生成器。服务器本身将根据上述逻辑决定使用哪个密钥生成器。

默认情况下,任何 EntityType 的“autoGeneratedKeyType”将为“None”或“Identity”,因此您需要为任何想要“自定义”密钥生成的类型设置此项。

设置完成后,调用 EntityManager.saveChanges 将自动调用服务器上的密钥生成,并将使用“真实”密钥保存新添加的实体,并使用这些新密钥更新客户端。

希望这可以帮助。

于 2013-04-24T19:28:40.447 回答