2011-09-27 252 views
3

我正在尝试将所有A实体与B实体一起加载到数据库中。他们之间的关系是每一个实体都有一个B实体。实体框架 - 使用子实体加载实体

我正在处理的项目有一个存储库模式,它具有如下的All()方法。

public class EFRepository<T> : IRepository<T> where T : class, IObjectWithChangeTracker 
     { 
private IObjectSet<T> objectset; 

     private IObjectSet<T> ObjectSet 
     { 
      get 
      { 
       if (objectset == null) 
       { 
        objectset = UnitOfWork.Context.GetObjectSet<T>(); 
       } 
       return objectset; 
      } 
     } 
    public virtual IQueryable<T> All() 
      { 
       return ObjectSet.AsQueryable(); 
      } 
    } 

有没有什么办法可以强制B实体进行急切加载。我发现的是,在All()方法返回的IQueryable中没有Include方法。我很高兴为repositroy添加新成员,以便它可以允许客户端使用急切的加载。但我该怎么做呢?

回答

1

您可以创建自己的扩展方法,这将允许您使用Include(path)反对任何IQueryable<T>

public static IQueryable<TSource> Include<TSource> 
    (this IQueryable<TSource> source, string path) 
{ 
    var objectQuery = source as ObjectQuery<TSource>; 
    if (objectQuery != null) 
    { 
    return objectQuery.Include(path); 
    } 
    return source; 
} 

有一个关于朱莉·勒曼的博客一个充分的解释:http://thedatafarm.com/blog/data-access/agile-entity-framework-4-repository-part-5-iobjectset/

+0

谢谢,我认为这是走 – Otake

4

问题是IQueryable不知道支持什么,Include是一个实体框架功能。你可以有一个使用LINQ to Objects的IQueryable,而Include在那里没有意义。最简单的方法是将All()的类型更改为IObjectSet,从中您应该可以访问Include扩展方法。

如果无法更改返回类型All,则必须以这样的方式构建查询,以便它们可以热切吸引子元素。

IList<Parent> parentsWithEagerLoadedChildren = parentRepo.All() 
    .Select(p => new {p, p.Children}).ToList() // EF will attach the children to each parent 
    .Select(p => p.p).ToList(); // Now that everything is loaded, select just the parents 
+0

感谢你的榜样工作,我很高兴地报告说,它发送一个单一的查询来获得所有的实体As和他们的Bs,这是我没有想到的。 – Otake

+0

关于IObjectSet,我无法访问包含方法。然后我看到这个http://stackoverflow.com/questions/2586351/ef4-linq-includestring-alternative-to-hard-coded-string这可能是一个更好的方式来解决它 – Otake