需要一个接受实体ID和包含的通用EF方法

时间:2013-01-15 19:39:42

标签: c# entity-framework generics frameworks entity

我正在使用Entity Framework 5并且有一个通用的存储库,其中有几个方法,如下面的两个Get()方法:

public TEntity GetById(int id)
{
    return DbSet.Find(id);
}

public TEntity Get(
    Expression<Func<TEntity, bool>> filter = null,
    IEnumerable<string> includePaths = null)
{
    IQueryable<TEntity> query = DbSet;

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

    if (includePaths != null)
    {
        query = includePaths.Aggregate(query, (current, includePath) => current.Include(includePath));
    }

    return query.SingleOrDefault();
}

这些都非常有用,但是当我想要进行稍微复杂的GetById()调用并同时检索一些实体引用时,如下所示:

var user = _userRepository.GetById(
    id,
    new List<string> { "Roles", "Invoices" });

我最终必须为每个实体推出特定于实体的(非通用的)GetById(id,includes)调用,以便我可以访问lambda中的特定Id字段,即UserId或InvoiceId等。< / p>

public User GetById(
    int id,
    IEnumerable<string> includes)
{
    return Get(
        (u => u.UserId == id),
        includes);
}

似乎我不能凭借我的平均EF技能,研究如何以通用方式将DbSet.Find(id)的优点与.Include()调用结合起来。

所以问题是 - 有没有办法编写一个通用的EF方法,我可以通过它的id来获取一个实体并包含一些引用,反过来又不需要编写特定于实体的GetById(id,includes)像我上面那样的电话。

提前致谢。

1 个答案:

答案 0 :(得分:6)

以下是我在通用存储库中的表现:

    public T GetBy(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes)
    {
        var result = GetAll();
        if (includes.Any())
        {
            foreach (var include in includes)
            {
                result = result.Include(include);
            }
        }
        return result.FirstOrDefault(predicate);
    }

注意这是使用lambda includes和FirstOrDefault而不是find但结果是一样的。

您可以查看我的通用存储库here的完整来源。

您可以通过以下方式致电:

var entity = myRepository.GetBy(e=>e.Id == 7, /*Includes*/ e=> e.ANavigationProperty, e=>e.AnotherNavProperty);

修改

我不再使用通用存储库,而是使用扩展方法动态构建查询。我发现这可以更好地重用。 (参见Composable Repositories上的文章)