将多个Include语句传递到存储库?

DDi*_*ita 0 linq-expressions entity-framework-4.1

我试图找到一种方法将包含语句的集合传递到我的存储库,以便我可以让它包含特定的实体.以下是我的存储库中的一些示例代码.

   public TEntity GetById(Guid id)
        {
            return id != Guid.Empty ? GetSet().Find(id) : null;
        }
   private IDbSet<TEntity> GetSet()
            {
                return _unitOfWork.CreateSet<TEntity>();
            }
Run Code Online (Sandbox Code Playgroud)

GetByID方法调用GetSet以返回实体集.我在想,如果我能以某种方式传入一组实体来包含(通过表达式)作为我的GetById的一部分,这样我就不必将GetSet公开给我的服务了.所以,像这样:

var entity = _repository.GetById(theId,e => {e.Prop1,e.Prop2,e.Prop3});

然后我可以将该表达式传递给我的GetSet方法并将其传递给include语句.思考?

Pai*_*ook 16

我最近在我的代码中做过类似的事情.以下是否适合您?

public TEntity GetById(Guid id, params Expression<Func<TEntity, object>>[] includeProperties)
    {
        if (id == Guid.Empty) return null;

        var set = _unitOfWork.CreateSet<TEntity>();
        foreach(var includeProperty in includeProperties)
        {
             set.Include(includeProperty);
        }
        return set.First(i => i.Id == id);
    }
Run Code Online (Sandbox Code Playgroud)

然后你会这样称呼它......

var entity = _repository.GetById(theId, e => e.Prop1, e=> e.Prop2, e=> e.Prop3);

我知道这并不完全符合你的模式,但我认为你可以根据需要重构它.


App*_*ere 8

我认为Paige Cook的代码不会如图所示.

我已经包含了一个代码的修改版本,它应该可以工作:

public TEntity GetById(Guid id, params Expression<Func<TEntity, object>>[] includeProperties)
{
    if (id == Guid.Empty) return null;

    IQueryable<TEntity> set = _unitOfWork.CreateSet<TEntity>();

    foreach(var includeProperty in includeProperties)
    {
         set = set.Include(includeProperty);
    }
    return set.First(i => i.Id == id);
}
Run Code Online (Sandbox Code Playgroud)

我只是通过跟踪Entity Framework生成的SQL来发现这一点,并且通过使用延迟加载来填充指定包含的实体,意识到原始代码只是给出了工作的错觉.

实际上,使用LINQ Aggregate方法应用Include语句有更简洁的语法,该方法位于链接到的博客文章中.我的帖子还通过回退到Find方法稍微改进了方法,当不需要包含时,还显示了如何使用类似语法实现"GetAll"方法的示例.

  • @PaigeCook有两个不同之处.首先,您必须使用Include语句的返回值.原始代码只是说**set.Include(includeProperty);**但我认为这必须是**set = set.Include(includeProperty);**.第二个变化是我发现我必须明确地将"set"声明为类型IQueryable <TEntity>,而不是使用"var".使用原始代码,您是否跟踪了SQL - 如果它有效,我很感兴趣!我的帖子中的最后一段描述了我的博客帖子中的内容,其中包括GetAll方法和terser LINQ版本. (3认同)