BreezeJS -在EFContextProvider问题中获取服务器端新创建的实体ID

本文关键字:创建 ID 实体 新创建 服务器端 EFContextProvider 问题 获取 BreezeJS | 更新日期: 2023-09-27 18:10:38

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

BreezeJS提供了一个有用的方法,通过子类化一个类型化的EFContextProvider来拦截对底层Data/ObjectContext的调用。父类公开了几个要重写的方法,例如下面的重写示例。这适用于更新/删除操作。但是,由于这发生在保存更改之前,因此此时还没有为插入生成ID。在这个类中,我找不到任何其他可以重写的方法。在最坏的情况下,我将扩展部分数据上下文(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);
    }

BreezeJS -在EFContextProvider问题中获取服务器端新创建的实体ID

目前在Breeze网站上的文档记录很差,但是…我将尽力在这里提供一些最起码的帮助。关于这个主题的更好的文档正在计划中…很快了:)

服务器端

Breeze通过IKeyGenerator接口的实现为您提供了在服务器上定制KeyGeneration的能力(您可以在Breeze中找到定义的接口)。WebApi源代码以及"后备"NumericKeyGenerator实现)。

在与EFContextProvider相同的程序集中,这个接口的任何自定义实现都将被Breeze自动发现。只支持一个实现,但是可以编写一个实现来支持您希望生成自定义键的所有可能的数据类型和属性。如果Breeze没有找到,它将默认使用上面提到的"NumericKeyGenerator"。

客户端

您将需要创建一个客户端"临时"密钥生成器。下面这一页有一些关于这个话题的讨论:这里。

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

您告诉Breeze客户端您想要通过EntityType调用自定义密钥生成。setProperties方法,像这样:

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

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

默认情况下,任何EntityType的"autoGeneratedKeyType"将是"None"或"Identity",所以你需要为任何类型设置这个,你想要"自定义"密钥生成。

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