breeze-在服务器上基于实体修改实体';s导航属性,然后保存

breeze-在服务器上基于实体修改实体';s导航属性,然后保存,breeze,Breeze,在服务器端的breeze中,是否有任何方法可以在BeforeSaveEntity(或保存之前的任何其他地方)中获取实体导航属性的“当前”值?我所说的“当前”是指数据库中存在的内容,以及合并的任何传入更改。这不是为了验证,而是基于父字段和子字段计算父属性的值(我不希望在客户端使用该值) 比如说, public class Parent { public ICollection<Child> Children{ get; set; } } 我想他们还不在这个背景下。我所能做的就是从

在服务器端的breeze中,是否有任何方法可以在BeforeSaveEntity(或保存之前的任何其他地方)中获取实体导航属性的“当前”值?我所说的“当前”是指数据库中存在的内容,以及合并的任何传入更改。这不是为了验证,而是基于父字段和子字段计算父属性的值(我不希望在客户端使用该值)

比如说,

public class Parent {
  public ICollection<Child> Children{ get; set; }
}

我想他们还不在这个背景下。我所能做的就是从数据库中检索现有的子项,并手动合并BeforeSaveEntities中的更改,这是一个麻烦

在Breeze用于保存的DbContext中不启用延迟加载。原因详见

您应该在中加载任何其他实体


下面是一个我在项目中如何做到这一点的例子。也许Breeze中应该包含MergeEntities和DetachEntities方法,以简化此操作

受保护的覆盖字典BeforeSaveEntities(字典保存映射)
{
//为计算创建一个单独的上下文,这样我们就不会污染主要的保存上下文
使用(var newContext=newmydbcontext(EntityConnection,false))
{
var parentFromClient=(Parent)saveMap[typeof(Parent)][0]。实体;
//将必要的数据加载到newContext中
var parentFromDb=newContext.Parents.Where(p=>p.ParentId==parentFromClient.ParentId)
。包括(“儿童”)。托利斯();
//…加载您需要的任何其他内容。。。
//将客户端实体附加到ObjectContext,这将合并它们并重新连接导航属性
var objectContext=((IObjectContextAdapter)newContext).objectContext;
var objectStateEntries=MergeEntities(objectContext,saveMap);
//…执行您的业务逻辑。。。
//从第二个上下文中删除实体,以便可以将它们保存在原始上下文中
分离实体(objectContext、saveMap);
}
返回saveMap;
}
///将客户端实体附加到ObjectContext,这将合并它们并重新连接导航属性
字典合并实体(ObjectContext oc、字典保存映射)
{
var osEntityInfo=新字典();
foreach(saveMap.Keys中的变量类型)
{
var entitySet=this.GetEntitySetName(类型);
foreach(saveMap[type]中的var entityInfo)
{
var entityKey=oc.CreateEntityKey(entitySet,entityInfo.Entity);
ObjectStateEntry-ose;
if(oc.ObjectStateManager.TryGetObjectStateEntry(entityKey,out-ose))
{
if(ose.State!=System.Data.Entity.EntityState.Deleted)
ose.ApplyCurrentValues(entityInfo.Entity);
}
其他的
{
oc.AttachTo(entitySet,entityInfo.Entity);
ose=oc.ObjectStateManager.GetObjectStateEntry(entityKey);
}
if(entityInfo.EntityState==Breeze.ContextProvider.EntityState.Deleted)
{
ose.Delete();
}
添加(ose,entityInfo);
}
}
返回OSEntityInfo;
}
///从ObjectContext中删除saveMap中的实体;这将分离它们的导航属性
静态实体(ObjectContext oc、Dictionary saveMap)
{
foreach(saveMap.Keys中的变量类型)
{
foreach(saveMap[type]中的var entityInfo)
{
尝试
{
拆离主管(实体信息实体);
}
抓住
{//无法分离该对象,因为它未附加
}
}
}
}

在Breeze用于保存的DbContext中不启用延迟加载。原因详见

您应该在中加载任何其他实体


下面是一个我在项目中如何做到这一点的例子。也许Breeze中应该包含MergeEntities和DetachEntities方法,以简化此操作

受保护的覆盖字典BeforeSaveEntities(字典保存映射)
{
//为计算创建一个单独的上下文,这样我们就不会污染主要的保存上下文
使用(var newContext=newmydbcontext(EntityConnection,false))
{
var parentFromClient=(Parent)saveMap[typeof(Parent)][0]。实体;
//将必要的数据加载到newContext中
var parentFromDb=newContext.Parents.Where(p=>p.ParentId==parentFromClient.ParentId)
。包括(“儿童”)。托利斯();
//…加载您需要的任何其他内容。。。
//将客户端实体附加到ObjectContext,这将合并它们并重新连接导航属性
var objectContext=((IObjectContextAdapter)newContext).objectContext;
var objectStateEntries=MergeEntities(objectContext,saveMap);
//…执行您的业务逻辑。。。
//从第二个上下文中删除实体,以便可以将它们保存在原始上下文中
分离实体(objectContext、saveMap);
}
返回saveMap;
}
///将客户端实体附加到ObjectContext,这将合并它们并重新连接导航属性
字典合并实体(ObjectContext oc、字典保存映射)
{
var osEntityInfo=新字典();
foreach(saveMap.Keys中的变量类型)
{
var entitySet=this.GetEntitySetName(类型);
foreach(saveMap[type]中的var entityInfo)
{
var entityKey=oc.CreateEntityKey(entitySet,entityInfo.Entity);
ObjectStateEntry-ose;
if(oc.ObjectStateManager.TryGetObjectStateEntry(entityKey,out-ose))
{
if(ose.State!=System.Data.Entity.EntityState.Deleted)
ose.ApplyCurrentValues(entityInfo.Entity);
}
其他的
{
主管附件(实体集,e
protected override bool BeforeSaveEntity(EntityInfo entityInfo) {
  if (entityInfo.Entity.GetType() == typeof(Parent) &&
  (entityInfo.EntityState == EntityState.Added || entityInfo.EntityState == EntityState.Updated)) {

   // Lazy load Parent's Children collection out of breeze's context 
   // so items are "current' (existing merged with changes)

   Parent parent = (Parent)entityInfo.Entity;
   Context.Entry(parent).Collection(p => p.Children).Load();

   // this throws exception Member 'Load' cannot be called for property
   // 'Children' because the entity of type 'Parent' does not exist in the context.
  }
}