Entity Framework 5. Multiple Include. Is this possible?

后端 未结 3 753
忘掉有多难
忘掉有多难 2020-12-20 20:50

I am trying to create a multiple include method in my repository to use as follows:

repository.Include(x => x.Images, x => x.Tags).First(x          


        
相关标签:
3条回答
  • 2020-12-20 21:20
    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();
          }
      }
    
    0 讨论(0)
  • 2020-12-20 21:28

    If you really want to create your own .Include non-extension method that allows for multiple paths in one call, internally translating to the already provided .Include method, you can do something like

    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;
    }
    

    This is pretty close to what you have already, but avoids the pitfall with Enumerable.Aggregate that you encountered: you'd have the same problem if you replace IQueryable<T> query with var query in my version.

    Note that using many .Include may harm performance. If it does in your situation, you can rewrite it to use multiple queries, which you can run one after the other in a transaction.

    Personally, as you can call the already provided .Include extension method (using System.Data.Entity;) on any IQueryable, I'd just write it as:

    repository.Posts.Include(x => x.Images).Include(x => x.Tags).First(x => x.Id == 1)
    
    0 讨论(0)
  • 2020-12-20 21:33

    I guess the shortest way is as follows:

    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;
        }
    }
    
    0 讨论(0)
提交回复
热议问题