6

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

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(this IQueryable source, Expression> path) where T : class;

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

谢谢你,

米格尔

4

3 回答 3

9

如果您真的想创建自己的.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可能会损害性能。如果在您的情况下确实如此,您可以重写它以使用多个查询,您可以在事务中一个接一个地运行这些查询。

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

repository.Posts.Include(x => x.Images).Include(x => x.Tags).First(x => x.Id == 1)
于 2012-12-11T12:05:38.383 回答
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();
      }
  }
于 2013-10-23T04:12:29.863 回答
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;
    }
}
于 2014-07-11T17:25:29.973 回答