【问题标题】:Is dbSet.Include pointless if called after dbSet is called?如果在调用 dbSet 之后调用 dbSet.Include 是否毫无意义?
【发布时间】:2016-07-26 18:06:58
【问题描述】:

假设我有这样的方法:

public DbSet<Ingredient> GetIngredients(int limit = 0)
        {
            return db.Ingredients;
        }

所以在我的控制器中,我可以这样调用:

var ingredients = GetIngredients()
.Include(i => i.AspNetUser)
.Include(i => i.AspNetUser1)
.Include(i => i.Ingredient_Category)
.Include(i => i.Measurement_Unit);

因为GetIngredients() 调用无论如何都会加载所有内容,它会毫无意义还是很慢?

如果是这样,有没有办法让GetIngredients() 使用各种包含作为参数?

最坏的情况我可以为每个场景在存储库中加载不同的方法(或者我应该这样做吗?感觉控制器应该说视图想要什么......或者 DbSet 是独一无二的EF 和我应该只从我的存储库返回 IEnumarables?)

非常感谢

【问题讨论】:

  • 您需要澄清您的问题,如果您是 1. 不执行延迟加载,2. 正在执行延迟加载,但您更愿意在单个查询中请求所有内容,则使用包含。现在,如果您包含具有多对多关系的多个包含,您可能会想要单独加载它们以避免 carstesian 生产。您的问题仍然不清楚,但您是否想单独包含,因为您想对包含的内容应用过滤?

标签: asp.net-mvc performance entity-framework linq


【解决方案1】:

因为 GetIngredients() 调用是无意义的还是缓慢的 还是要加载所有内容?

不,您的查询只有在您咨询(例如,通过 foreach)或调用 ToListToArray 扩展方法后才会执行

有没有办法让 GetIngredients() 使用各种包含作为 参数?

public IQueryable<Ingredient> GetIngredients(List<Expression<Func<TEntity, object>>> includes = null)
{
     IQueryable<TEntity> query = db.Ingredients;

     if (includes != null)
     {
         query = includes.Aggregate(query, (current, include) => current.Include(include));
     }
     return query;
}

关于您的最后一个问题,您应该在处理 DbContext 之前从数据库中获取数据。因此,如果您从控制器调用此方法以将结果作为参数传递给您的视图,则将返回类型更改为 IEnumerable&lt;Ingredient&gt; 并在方法 query.ToList(); 的末尾调用 ToList 以确保您正在执行在将结果传递给视图之前进行查询。

【讨论】:

  • “不,您的查询在您咨询它(例如,通过 foreach)或调用 ToList 或 ToArray 扩展方法之前不会被执行”正是我需要知道的!
猜你喜欢
  • 2011-11-09
  • 1970-01-01
  • 2017-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多