【问题标题】:Eager Loading of Navigation Properties急切加载导航属性
【发布时间】:2015-09-27 18:49:51
【问题描述】:

在我的存储库中,我尝试使用预先加载来加载相关实体。不知道为什么,但是当我返回特定实体的所有实例时,似乎返回了相关实体,但是当我限制返回的结果时,相关实体不包含在结果中。

服务层中的这段代码返回所有订单,包括相关的 Customer、OrderItem 和 Product 实体:

public async Task<IEnumerable<Order>> GetOrdersAsync()
{
    return await _repository.GetAsync(null, q => q.OrderByDescending(p => p.CreatedDate), "Customer", "OrderItems", "OrderItems.Product");
}

在存储库中:

public async Task<IEnumerable<Order>> GetAsync(Expression<Func<Order, bool>> where = null, Func<IQueryable<Order>, IOrderedQueryable<Order>> orderBy = null, params string[] navigationProperties)
{
    IQueryable<Order> query = _context.Set<Order>();

    if (where != null)
    {
        query = query.Where(where);
    }

    //Apply eager loading
    foreach (string navigationProperty in navigationProperties)
            query = query.Include(navigationProperty);

    if (orderBy != null)
    {
        return await orderBy(query).ToListAsync();
    }
    else
    {
        return await query.ToListAsync();
    }
}

服务层中的这段代码通过 id 获取订单,但由于某种原因没有返回相关的 Customer、OrderItem 和 Product 实体:

public async Task<Order> GetOrderByIdAsync(long id)
{
  return await _repository.GetByIdAsync(id, "Customer", "OrderItems", "OrderItems.Product");
}

在存储库中:

public async Task<Order> GetByIdAsync(long id, params string[] navigationProperties)
{
    DbSet<Order> dbSet = _context.Set<Order>();

    foreach (string navigationProperty in navigationProperties)
        dbSet.Include(navigationProperty);

    return await dbSet.FindAsync(id);
}

我看到的两种存储库方法之间的一个区别是,一个是在包含导航属性之前将 _context.Set() 强制转换为 IQueryable,而另一个是直接在 DbSet 本身上调用 Include。这应该重要吗?

【问题讨论】:

  • 实际上...我不确定 IQueryable 是否具有与 DbSet 相同的 Include() 功能。

标签: entity-framework entity-framework-6


【解决方案1】:

因此,不起作用的存储库方法错误地使用了 DBSet.Include。 Include 实际上是 DBQuery 类上的一个方法,DBSet 继承自该类。对于我包含的每个导航属性,我需要使用 DBQuery.Include 将查询替换为查询的新实例。所以我将实现更改为:

public async Task<Order> GetByIdAsync(long id, params string[] navigationProperties)
{
    DbQuery<Order> dbQuery = _context.Set<Order>();

    foreach (string navigationProperty in navigationProperties)
        dbQuery = dbQuery.Include(navigationProperty);

    return await dbQuery.Where(o => o.Id == id).FirstOrDefaultAsync();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多