2016-03-31 14 views
0

kaydetmeden önce, seyir özelliklerini var üzerine sunucu tarafında rüzgârda BeforeSaveEntity bir Teşekkülün seyir tesisin "geçerli" değerini almak için herhangi bir yolu var mı (ya da başka bir yerde önce kaydetmek) tabanlı sunucuda, bir varlık değiştirmek ? Güncel olarak, veritabanında var olan, gelen tüm değişiklikler ile birleştiği anlamına gelir. Bu, doğrulama için değil, daha ziyade her ikisi de temel alarak (istemcisinde istemediğim) bir üst özellik için bir hesap yapıyorum. ebeveyn alanları ve çocuk alanları ... Örneğinesinti - bu

,

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

Henüz DBContext içinde olmadıklarını düşünüyorum. Yapabileceğim tek şey, mevcut çocukları veritabanından almak ve bir güçlük olan BeforeSaveEntities'deki değişiklikleri birleştirmek.

cevap

1

Geç yükleme Breeze tasarrufu için kullandığı DBContext etkinleştirmek değildir. Nedeni this SO answer'da ayrıntılandırılmıştır.

Bir separate DbContext herhangi bir ek öğeleri yüklemek gerekir.


İşte bir projede nasıl yaptığımın bir örneği. Belki bunu yapmak için daha basit hale getirmek için Breeze ile MergeEntities ve DetachEntities yöntemleri dahil edilmelidir.

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

Bu cevabı gördüm ancak gelen tüm değişikliklerle navigasyonun mevcut durumuna ihtiyacım var. Bu yüzden, "Ebeveynlerim" için herhangi bir "Çocuklar" değişimini savrulmak ve değişiklik yapmak zorunda mıyım? – user210757

+0

Bir varlığın ve ilgili varlıklarının durumu hakkında bilinmesi gereken bir tasarrufla nasıl başa çıkardınız? – user210757

+0

Cevabım için uzun bir örnek ekledim. Bu yardımcı olur umarım. –