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

Ber*_*ern 3 c# generics frameworks entity entity-framework

我正在使用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();
}
Run Code Online (Sandbox Code Playgroud)

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

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

我最终不得不为每个实体推出特定于实体的(非通用的)GetById(id,includes)调用,以便我可以访问lambda中的特定Id字段,即UserId或InvoiceId等.

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

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

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

提前致谢.

Not*_*ple 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);
    }
Run Code Online (Sandbox Code Playgroud)

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

您可以在此处查看我的通用存储库的完整源代码.

您可以通过以下方式调用此方法:

var entity = myRepository.GetBy(e=>e.Id == 7, /*Includes*/ e=> e.ANavigationProperty, e=>e.AnotherNavProperty);
Run Code Online (Sandbox Code Playgroud)

编辑:

我不再使用通用存储库,而是使用扩展方法来动态构建查询.我发现这可以更好地重用.(请参阅我在这里关于可组合存储库的文章)