BreezeJS - 在EFContextProvider中获取服务器端新创建的实体ID会遇到麻烦

时间:2013-04-24 14:39:11

标签: c# asp.net asp.net-mvc breeze

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

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

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

1 个答案:

答案 0 :(得分:3)

目前Breeze网站上的文档记录很少,但是......我会尝试在这里提供至少一些帮助。关于这个主题的更好的文档已经计划好了......现在很快就会实现:)

服务器端

Breeze为您提供了通过实现IKeyGenerator接口在服务器上自定义KeyGeneration的功能(您可以找到Breeze.WebApi源中定义的接口以及“后备”NumericKeyGenerator实现)。

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

客户端

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

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

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

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

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

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

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

希望这有帮助。