实体框架预先加载所有导航属性
本文关键字:导航 属性 加载 框架 实体 | 更新日期: 2023-09-27 18:31:23
>我正在使用带有DI和IoC的存储库模式。
我在存储库中创建了一个函数:
T EagerGetById<T>(Guid id, string include) where T : class
{
return _dbContext.Set<T>().Include(include).Find(id);
}
这将急切地在我的实体权限中加载一个导航属性。
但是如果我的实体看起来像这样:
public class Blog : PrimaryKey
{
public Author Author {get;set;}
public ICollection<Post> Posts {get;set;}
}
我将如何急切地加载Author
和Posts
?我真的必须这样做吗:
_dbContext.Set<T>().Include("Author").Include("Posts").Find(id);
不可避免地产生这样的函数:
T EagerGetById<T>(Guid id, string include, string include2, string include3) where T : class
{
return _dbContext.Set<T>().Include(include).Include(include2).Include(include3).Find(id);
}
因为这对于Generic
存储库来说效率非常低下!
如果您不想使用字符串,也可以通过使用返回要预先加载的导航属性的表达式对任何 N 个包含执行相同的操作。(原文来源于此处)
public IQueryable<TEntity> GetAllIncluding(params Expression<Func<TEntity, object>>[] includeProperties)
{
IQueryable<TEntity> queryable = GetAll();
foreach (Expression<Func<TEntity, object>> includeProperty in includeProperties)
{
queryable = queryable.Include<TEntity, object>(includeProperty);
}
return queryable;
}
如果需要所有导航属性,则别无选择,只能从数据库中读取所有导航属性。您可以在查询中Include
它们,也可以提前将它们读取到 DbSet 的本地数据中。
如果要将多个包含传递给方法,只需像这样定义它:
T EagerGetById<T>(Guid id, params string[] includes)
您的用户将能够呼叫EagerGetById(id, "inc1", "inc2", ...)
在方法中,只需为 includes
数组中的每个元素调用 Include
。
您应该准备好params
关键字