问题
I'm using the Repository pattern with DI and IoC.
I have created a function in my Repository:
T EagerGetById<T>(Guid id, string include) where T : class
{
return _dbContext.Set<T>().Include(include).Find(id);
}
This will eagerly load one navigation property in my entity right.
But if my entity looks like this:
public class Blog : PrimaryKey
{
public Author Author {get;set;}
public ICollection<Post> Posts {get;set;}
}
How would I get eager loading for Author and Posts? Would I literally have to do:
_dbContext.Set<T>().Include("Author").Include("Posts").Find(id);
inevitably producing a function like this:
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);
}
Because that would be really inefficient for a Generic Repository!
回答1:
If you don't want to use strings, you can also do the same for any N number of includes by using an expression which returns the navigation properties to be eager loaded. (original source here)
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;
}
回答2:
If you need all navigation properties, you have no choice but to read all of them from the database. You either Include them in your query, or read them in advance to the DbSet's local data.
If you want to pass multiple includes to your method, just define it like this:
T EagerGetById<T>(Guid id, params string[] includes)
Your users will be able to call EagerGetById(id, "inc1", "inc2", ...)
Inside your method, just call Include for every element in the includes array.
You should ready about the params keyword
来源:https://stackoverflow.com/questions/18804850/entityframework-eager-load-all-navigation-properties