2010-09-01 179 views
3

我正在嘗試從我的上下文執行LoadProperty操作來加載導航屬性的導航屬性。EF 4.0 - 導航屬性的導航屬性

我的設置是我有一個EntityA,它包含EntityB的列表,每個EntityB包含一個EntityC的列表。我做了以下編程:

public virtual List<T> LoadProperty(List<T> entities, string property) 
{ 
    using (MyContext context = new MyContext()) 
     foreach (T entity in entities) 
     { 
      context.AttachTo(typeof(T).Name, entity); 
      context.LoadProperty(entity, property); 
     } 

    return entities; 
} 

我把它看作:

LoadProperty(entityA, "EntityB.EntityC"); 

我知道NavigationProperty路徑是正確的,但是,這是行不通的。有沒有辦法讓這個加載?

編輯:使用 工作示例包括:

using (MyContext context = new MyContext()) 
{ 
    var query = from entityA in context.EntityA.Include("EntityB").Include("EntityB.EntityC") 
       where entityA.Id == id 
       select entityA; 

    return query.ToList(); 
} 
+0

您不需要同時調用containeded(「EntityB」)和Include(「EntityB.EntityC」)。後面的一個就足夠了。 – 2010-09-01 18:23:21

+0

EntityC是EntityB上的一個集合,因此EntityB上沒有EntityC。 – 2010-09-02 01:16:56

回答

1

首先,你的方法調用context.AttachTo(typeof(T).Name,entity)是不正確的,你會得到一個InvalidOperationException。 ObjectContext.AttachTo Method顯示:

public void AttachTo(string entitySetName, Object entity) 

所以我們需要通過EntitySet的名稱,而不是實體名稱本身。但好消息是我們可以通過具有實體名稱從MetadataWorkspace獲得EntitySet名稱。下面的代碼顯示瞭如何。

現在,如果你有3級的對象組成,EntityB和EntityC的類型EntityCollections的導航性能,那麼我不認爲你可以用一個調用LoadProperty加載他們兩個,但可以通過調用LoadProperty做兩次,這裏是它是如何做:

using System.Data.Metadata.Edm; 

public virtual List<T> LoadProperty(List<T> entities, string property) { 
    using (TrialsContext context = new TrialsContext()) { 

     EntityContainer container = context.MetadataWorkspace 
              .GetEntityContainer(context.DefaultContainerName, 
                   DataSpace.CSpace); 
     EntitySetBase entitySet = container.BaseEntitySets 
              .Where(item => 
                item.ElementType.Name.Equals(typeof(T).Name)) 
              .FirstOrDefault(); 

     foreach (T entity in entities) { 
      context.AttachTo(entitySet.Name, entity); 
      context.LoadProperty(entity, property); 
     } 

    return entities; 
} 

而且你將它稱爲:


// To load EntityA Nav property: 
LoadProperty(entityB, "EntityA"); 

// To Load EntityC Nav property: 
//Let's assume the nav property name for EntityC on EntityB is EntityCList 
LoadProperty(entityB, "EntityCList"); 

這樣,您將有充分的對象圖構造。

1

「我知道NavigationProperty路徑是正確的......」不,這不是。不是一個列表,它不是。試用Include,你會看到相同的結果。你不能用1:*屬性來做到這一點。

我無法想象這是針對您問題的最有效的解決方案,但您並未真正瞭解爲什麼您認爲您需要這樣做。

+0

我用Include對它進行了測試,它工作。查看編輯的票證。當我的EntityA實例通過時也需要這個。初始屏幕可能不需要某個導航屬性,但後續屏幕可能會需要。我不希望使用Includes重新加載實體,而是希望能夠調用LoadProperty來加載我需要的屬性。 LoadProperty方法適用於加載屬性「EntityB」,但不適用於「EntityB.EntityC」。 – Brandon 2010-09-01 17:41:31

+0

如果'Include()'起作用,它將比顯式加載更高效。但投影到視圖模型將比任何一個更有效。 – 2010-09-01 17:50:47

+0

查看'LoadProperty'的文檔,我看不到它有意支持虛線路徑的任何跡象。 – 2010-09-01 17:52:04