实体框架 - 使用子实体加载实体

时间:2011-09-27 15:28:18

标签: c# entity-framework eager-loading

我想要的是将数据库中的所有A实体与B实体一起加载。它们之间的关系是每个A权利都有一个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实体急切加载。我发现在IQueryable上没有从All()方法返回的Include方法。我很高兴为repositroy添加一个新成员,因此它可以允许客户端使用预先加载。但是我怎么能这样做呢?

2 个答案:

答案 0 :(得分:4)

问题是IQueryable不知道支持它的是什么,而Include是实体框架功能。您可以使用IQueryable来使用LINQ to Objects,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

答案 1 :(得分: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;
}

有关Julie Lerman博客的完整解释:http://thedatafarm.com/blog/data-access/agile-entity-framework-4-repository-part-5-iobjectset/