C# BreezeJS-在EFContextProvider中获取服务器端新创建的实体ID
我正在尝试确定使用BreezeJS保存的新添加/插入记录的ID。这样做的目的是广播和通知正在收听的客户端更改,以便他们可以在必要时更新其视图 BreezeJS提供了一种有用的方法,通过对类型化的EFContextProvider进行子类化来拦截对其底层数据/对象上下文的调用。父级公开了几个要重写的方法,例如下面被重写的示例。这对于更新/删除操作都很有效。但是,由于这是在保存更改之前发生的,因此此时没有为插入生成ID。我在这个类中找不到任何其他可以重写的方法。在最坏的情况下,我将扩展部分datacontext(the),但我觉得将此通知系统划分为多个类是不合适的。建议C# BreezeJS-在EFContextProvider中获取服务器端新创建的实体ID,c#,asp.net,asp.net-mvc,breeze,C#,Asp.net,Asp.net Mvc,Breeze,我正在尝试确定使用BreezeJS保存的新添加/插入记录的ID。这样做的目的是广播和通知正在收听的客户端更改,以便他们可以在必要时更新其视图 BreezeJS提供了一种有用的方法,通过对类型化的EFContextProvider进行子类化来拦截对其底层数据/对象上下文的调用。父级公开了几个要重写的方法,例如下面被重写的示例。这对于更新/删除操作都很有效。但是,由于这是在保存更改之前发生的,因此此时没有为插入生成ID。我在这个类中找不到任何其他可以重写的方法。在最坏的情况下,我将扩展部分datac
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);
}
protectedoverride bool BeforeSaveEntity(EntityInfo EntityInfo){
var hubContext=GlobalHost.ConnectionManager.GetHubContext();
if(entityInfo.EntityState==EntityState.Modified){
试一试{
hubContext.Clients.All.handleEntityUpdate(新{
EntityType=entityInfo.Entity.GetType().Name,
Key=((动态)(entityInfo.Entity)).Id
});
}
捕获(异常ep){
//未能通知客户。*哦,没什么大不了的。
//试试,接住,柯利,柯利,柯利。
}
}
else if(entityInfo.EntityState==EntityState.Deleted){
试一试{
hubContext.Clients.All.handleEntityDelete(新){
EntityType=entityInfo.Entity.GetType().Name,
Key=((动态)(entityInfo.Entity)).Id
});
}
捕获(异常ep){
//未能通知客户。*哦,没什么大不了的。
//试试,接住,柯利,柯利,柯利。
}
}
返回base.BeforeSaveEntity(entityInfo);
}
这在Breeze网站上的文档记录得很差,但是。。。我会尽量在这里提供一些起码的帮助。关于这个主题的更好的文档正在计划中。。。real soon now:)
服务器端
Breeze为您提供了通过IKeyGenerator接口实现在服务器上自定义密钥生成的能力(您可以找到Breeze.WebApi源中定义的接口以及“回退”NumericKeyGenerator实现)
Breeze将自动发现与EFContextProvider位于同一程序集中的此接口的任何自定义实现。只支持一个实现,但可以编写一个实现来支持您希望为其生成自定义密钥的所有可能的数据类型和属性。如果Breeze没有找到,它将默认为上面提到的“NumericKeyGenerator”
客户端
然后需要创建客户端“临时”密钥生成器。在下一页上有一些关于此主题的讨论:
其思想是,Breeze将使用此“临时”密钥生成器为任何新创建的实体(指定类型)生成临时密钥。保存这些实体后,Breeze将使用上述服务器端机制生成一个“真实”密钥,并将保存这些实体。然后,Breeze会将temp->real键的映射返回给客户端,并使用该映射自动用正确的“real”键更新客户端实体
告诉Breeze客户端,您希望通过EntityType.setProperties方法调用自定义密钥生成,如下所示:
var regionType = testFns.metadataStore.getEntityType("Region");
regionType.setProperties({
autoGeneratedKeyType: AutoGeneratedKeyType.KeyGenerator }
);
请注意,您只是告诉Breeze使用自定义密钥生成器。服务器本身将根据上述逻辑决定使用哪个密钥生成器
默认情况下,任何EntityType的“autoGeneratedKeyType”都将是“None”或“Identity”,因此您需要为希望生成“自定义”密钥的任何类型设置此选项
设置此项后,调用EntityManager.saveChanges将自动调用服务器上的密钥生成,并将使用“真实”密钥保存新添加的实体,并使用这些新密钥更新客户端
希望这能有所帮助。我感谢你这么长时间没有给你答案。谢谢你,杰!