为什么EF eager loading包含不按预期工作?

时间:2014-01-15 16:28:36

标签: c# entity-framework eager-loading

我有这个存储库,

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private readonly DbContext context;
    private readonly DbSet<TEntity> dbEntitySet;

    public Repository(DbContext context)
    {
        if (context == null)
            throw new ArgumentNullException("context");

        this.context = context;
        this.dbEntitySet = context.Set<TEntity>();
    }

    public IEnumerable<TEntity> GetAll()
    {
        return this.dbEntitySet;
    }

    public IEnumerable<TEntity> GetAll(string include)
    {
        return this.dbEntitySet.Include(include);
    }

    public IEnumerable<TEntity> GetAll(string[] includes)
    {
        foreach (var include in includes)
            this.dbEntitySet.Include(include);

        return this.dbEntitySet;
    }

    public void Create(TEntity model)
    {
        this.dbEntitySet.Add(model);
    }

    public void Update(TEntity model)
    {
        this.context.Entry<TEntity>(model).State = EntityState.Modified;
    }

    public void Remove(TEntity model)
    {
        this.context.Entry<TEntity>(model).State = EntityState.Deleted;
    }

    public void Dispose()
    {
        this.context.Dispose();
    }
}

我遇到的问题是这个方法:

public IEnumerable<TEntity> GetAll(string[] includes)
{
    foreach (var include in includes)
        this.dbEntitySet.Include(include);

    return this.dbEntitySet;
}

当我在返回之前运行并设置断点时,就好像忽略了 foreach

上面的方法工作正常:

public IEnumerable<TEntity> GetAll(string include)
{
    return this.dbEntitySet.Include(include);
}

要打电话,我基本上这样做:

var a = this.Repository.GetAll(new string[] { "ForbiddenUsers", "ForbiddenGroups" }).ToList();

取回结果但不包括包含:D如果我将调用修改为:

var a = this.Repository.GetAll("ForbiddenUsers").ToList();

工作正常。

有人能为我提供解决方案吗?

2 个答案:

答案 0 :(得分:7)

将您的方法更改为:

public IEnumerable<TEntity> GetAll(string[] includes)
{
    var query = this.dbEntitySet;

    foreach (var include in includes)
        query = query.Include(include);

    return query;
}

Include方法不会改变DbSet,它只会返回一个包含新内容的DbQuery

答案 1 :(得分:1)

此代码不正确:

public IEnumerable<TEntity> GetAll(string[] includes)
{
    foreach (var include in includes)
       this.dbEntitySet.Include(include);

    return this.dbEntitySet;
}

正确的代码如下:

public IEnumerable<TEntity> GetAll(string[] includes)
{
     IQueryable<T> query = this.dbEntitySet;

     foreach (var include in includes)
         query = query.Include(include);

    return query;
}

在我的位置,我将使用这样的Lambda表达式:

public IEnumerable<TEntity> GetAll(Expression<Func<T, object>>[] includes)
{
     IQueryable<T> query = this.dbEntitySet;

     foreach (var include in includes)
         query = query.Include(include);

     return query;
}