实体框架5.多个包含。这可能吗?

时间:2012-12-11 11:54:25

标签: entity-framework

我正在尝试在我的存储库中创建一个多包含方法,使用方法如下:

repository.Include<Post>(x => x.Images, x => x.Tags).First(x => x.Id == 1)

我试了一下:

public IQueryable<T> Include<T>(params Expression<Func<T, Object>>[] paths) where T : class {
  return paths.Aggregate(_context.Set<T>(), (x, path) => x.Include(path));
} // Include

但我收到错误:

无法将类型'System.Linq.IQueryable'隐式转换为'System.Data.Entity.DbSet'。

请注意,原始包含如下:

public static IQueryable Include(   这个IQueryable来源,   表达&GT;路径 )其中T:class;

我可以在不将我的存储库方法变为静态的情况下完成这项工作吗?

谢谢,

米格尔

3 个答案:

答案 0 :(得分:8)

如果您真的想要创建自己的.Include非扩展方法,允许在一个调用中使用多个路径,在内部转换为已提供的.Include方法,则可以执行类似

public IQueryable<T> Include<T>(params Expression<Func<T, object>>[] paths)
    where T : class
{
    IQueryable<T> query = _context.Set<T>();
    foreach (var path in paths)
        query = query.Include(path);
    return query;
}

这与您已经接近的情况非常接近,但避免了您遇到的Enumerable.Aggregate陷阱:如果您将IQueryable<T> query替换为var query,我会遇到同样的问题版本

请注意,使用许多.Include可能会损害性能。如果它在您的情况下,您可以重写它以使用多个查询,您可以在事务中一个接一个地运行。

就个人而言,您可以在任何.Include上调用已提供的using System.Data.Entity;扩展方法(IQueryable),我只需将其写为:

repository.Posts.Include(x => x.Images).Include(x => x.Tags).First(x => x.Id == 1)

答案 1 :(得分:0)

public ICollection<SomeClass> Filter(string name, int skip, int take,out int total, params Expression<Func<SomeClass, object>>[] includeProperties) {
      IQueryable<SomeClass> query = Session.All<SomeClass>().AsNoTracking();
      //query = includeProperties.Aggregate(query, (current, property) => current.Include(property));
      foreach (var property in includeProperties){
          query = query.Include(property);
      }

      if (!string.IsNullOrWhiteSpace(name)){
          query = query.Where(x => x.Name.Contains(name));
          var page = query.OrderBy(x => x.Name)
              .Skip(skip)
              .Take(take)
              .GroupBy(p => new{Total = query.Count()})
              .FirstOrDefault();
         total = (page != null) ? page.Key.Total : 0;
         if (page == null) {
            return new List<SomeClass>();
         }
         return  page.ToList();
      } else {
          var page = query.OrderBy(x => x.Name)
              .Skip(skip)
              .Take(take)
              .GroupBy(p => new { Total = query.Count() })
              .FirstOrDefault();
          total = (page != null) ? page.Key.Total : 0;
          if (page == null) {
             return new List<SomeClass>();
          }
          return page.ToList();
      }
  }

答案 2 :(得分:0)

我想最短的方法如下:

public static class LinqExtensions
{
    /// <summary>
    /// Acts similar of .Include() LINQ method, but allows to include several object properties at once.
    /// </summary>
    public static IQueryable<T> IncludeMultiple<T>(this IQueryable<T> query, params Expression<Func<T, object>>[] paths)
        where T : class
    {
        foreach (var path in paths)
            query = query.Include(path);

        return query;
    }
}