我如何构建一个函数,允许我通过参数传递EF的几个包含
本文关键字:参数传递 EF 包含 几个 允许我 函数 何构建 构建 一个 | 更新日期: 2023-09-27 17:49:55
我正在编写一个ef支持的存储库,该存储库具有与每个实体类型相关联的包的概念,这些实体类型为其常用的子实体提供. include。例如,我有一个像这样的函数
private static IQueryable<Foo> GetFooPackage(Entities context)
{
return context.Foo
.Include(target => target.Bar)
.Include(target => target.FooBar)
}
这就是当我运行我的"get"方法时,返回的数据有一个一致的分组。然而,我希望能够在具体案例的基础上进行扩展。我希望能够做一些像
这样的事情public static Foo GetFoo(int fooId, params Expression<Func<Foo, T>>[] extraIncludes)
{
using (Entities context = GetContext(null))
{
IQueryable<Foo> package = GetFooPackage(context);
extraIncludes.ToList().ForEach(expression => package.Include(expression));
return package.FirstOrDefault(target => target.FooId == fooId);
}
}
让我失望的是T部分。我知道这个例子没有正确地引用T泛型。它只是示例的占位符。我不确定如何塑造它,这样我才能做我想做的事。最终,这是为了使EF生成的SQL尽可能小而简洁。你有什么建议吗?它是在一个断开连接的服务中使用的,所以我不能依靠延迟加载来简单地获取更多的数据,如果它丢失了。一旦我获取了数据,我需要一次获取它,而进行第二次获取实际上是不现实的。
谢谢!
public IQueryable<T> GetAllIncluding(params Expression<Func<T, object>>[] includes)
{
var query = DbSet.AsNoTracking();
query = includes.Aggregate(query, (current, includeProperty) => current.Include(includeProperty));
return query;
}
MyGenericRepository<A>().GetAllIncluding(x=> x.B, x=> x.C).FirstOrDefault()
在这里找到答案:如何在EF中包含2个导航属性?
对于那些由于DbSet.AsNoTracking
而无法使用公认答案的人,这里有一个替代方案:
public IEnumerable<TEntity> Retrieve(params Expression<Func<TEntity, object>>[] relations)
{
IQueryable<TEntity> query = this.Entities;
foreach (var relation in relations)
query = query.Include(relation);
return query;
}
该版本循环遍历关系数组,并在每次迭代时展开查询。