2010-09-01 116 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