2016-03-31 2 views
0

サーバー側でBeforeSaveEntity(または保存前の他の場所)のエンティティのナビゲーションプロパティの「現在の」値を取得する方法はありますか?現時点では、データベースに存在するものを意味します。受信した変更はすべてマージされます。これは検証用ではなく、(クライアント上では必要ない)親プロパティの値を計算します。親フィールドと子フィールド...例えばbreeze - 保存する前にサーバー上のエンティティをナビゲーションプロパティに基づいて変更する

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

。 。 。

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. 
    } 
} 

私はそれらがまだDBContextにないと思っています。私が考えることができるのは、データベースから既存の子を取得し、BeforeSaveEntitiesの変更を手動でマージすることです。これは面倒です。

答えて

1

Breezeが保存に使用するDbContextでレイジーローディングが有効になっていません。その理由はthis SO answerで詳しく説明されています。

separate DbContextに追加のエンティティを読み込む必要があります。


ここでは、プロジェクトでどのように行ったかの例を示します。おそらくMergeEntitiesメソッドとDetachEntitiesメソッドをBreezeに含めて、これを簡単にする必要があります。

protected override Dictionary<Type, List<EntityInfo>> BeforeSaveEntities(Dictionary<Type, List<EntityInfo>> saveMap) 
{ 
    // create a separate context for computation, so we don't pollute the main saving context 
    using (var newContext = new MyDbContext(EntityConnection, false)) 
    { 
     var parentFromClient = (Parent)saveMap[typeof(Parent)][0].Entity; 

     // Load the necessary data into the newContext 
     var parentFromDb = newContext.Parents.Where(p => p.ParentId == parentFromClient.ParentId) 
      .Include("Children").ToList(); 

     // ... load whatever else you need... 

     // Attach the client entities to the ObjectContext, which merges them and reconnects the navigation properties 
     var objectContext = ((IObjectContextAdapter)newContext).ObjectContext; 
     var objectStateEntries = MergeEntities(objectContext, saveMap); 

     // ... perform your business logic... 

     // Remove the entities from the second context, so they can be saved in the original context 
     DetachEntities(objectContext, saveMap); 
    } 
    return saveMap; 
} 

/// Attach the client entities to the ObjectContext, which merges them and reconnects the navigation properties 
Dictionary<ObjectStateEntry, EntityInfo> MergeEntities(ObjectContext oc, Dictionary<Type, List<EntityInfo>> saveMap) 
{ 
    var oseEntityInfo = new Dictionary<ObjectStateEntry, EntityInfo>(); 
    foreach (var type in saveMap.Keys) 
    { 
     var entitySet = this.GetEntitySetName(type); 
     foreach(var entityInfo in saveMap[type]) 
     { 
      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); 
      } 
      else 
      { 
       oc.AttachTo(entitySet, entityInfo.Entity); 
       ose = oc.ObjectStateManager.GetObjectStateEntry(entityKey); 
      } 

      if (entityInfo.EntityState == Breeze.ContextProvider.EntityState.Deleted) 
      { 
       ose.Delete(); 
      } 
      oseEntityInfo.Add(ose, entityInfo); 
     } 
    } 
    return oseEntityInfo; 
} 

/// Remove the entities in saveMap from the ObjectContext; this separates their navigation properties 
static void DetachEntities(ObjectContext oc, Dictionary<Type, List<EntityInfo>> saveMap) 
{ 
    foreach (var type in saveMap.Keys) 
    { 
     foreach (var entityInfo in saveMap[type]) 
     { 
      try 
      { 
       oc.Detach(entityInfo.Entity); 
      } 
      catch 
      { // the object cannot be detached because it is not attached 
      } 
     } 
    } 
} 
+0

私はその答えを見ましたが、私はどのような変化があってもナビゲートの現在の状態が必要です。だから私はsavemapをループし、 "Parent"の "Children"の変更をマージする必要がありますか? – user210757

+0

エンティティとエンティティの受信状態を知る必要があるセーブをどのように処理しますか? – user210757

+0

答えに長い事例を追加しました。お役に立てれば。 –

関連する問題