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

时间:2011-08-26 15:25:30

标签: entity-framework-4.1 linq-expressions

我试图想出一种方法将一组include语句传递到我的存储库中,这样我就可以让它包含特定的实体。以下是我的存储库中的一些示例代码。

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

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

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

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

4 个答案:

答案 0 :(得分: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);
    }

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

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

我知道这并不完全符合您的模式,但我认为您可以根据需要进行重构。

答案 1 :(得分: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);
}

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

applying the Include statements using the LINQ Aggregate method实际上有一个更简洁的语法,它位于链接到的博客文章中。我的帖子还通过回退到Find方法稍微改进了方法,当不需要包含时,还显示了如何使用类似语法实现“GetAll”方法的示例。

答案 2 :(得分:0)

include方法可以在你的linq查询中串起来,如下所示:

var result = (from i in dbContext.TableName.Include("RelationProperty")
                                           .Include("RelationProperty")
                                           .Include("RelationProperty")
                select i);

答案 3 :(得分:0)

出于多种原因,将上下文存储在非本地空间中是个坏主意。

我修改了Steve的代码并为我的ASP.NET MVC项目获取了这个代码:

public aspnet_User FirstElement(Func<aspnet_User, bool> predicate = null, params Expression<Func<aspnet_User, object>>[] includes)
    {
        aspnet_User result;
        using (var context = new DataContext())
        {
            try
            {
                var set = context.Users.AsQueryable();

                for (int i = 0; i < includes.Count(); i++ )
                    set = set.Include(includes[i]);

                if (predicate != null)
                    result = set.ToList().FirstOrDefault(predicate);
                else
                    result = set.ToList().FirstOrDefault();
            }
            catch
            {
                result = null;
            }
        }

        return result;
    }