我目前正在实现存储库模式,它允许我将我的类和上下文传递到通用存储库。这很完美。我感兴趣的方法是Get and Find。 find允许我指定和“命令”,一些“where”语句和一些“include”语句。这很理想。
public class GeneralRepository<TEntity> : IGeneralRepository<TEntity> where TEntity : class
{
readonly GamesContext context;
readonly DbSet<TEntity> db;
public GeneralRepository(GamesContext existingContext)
{
context = existingContext;
db = context.Set<TEntity>();
}
public TEntity Get(object id)
{
return db.Find(id);
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
{
IQueryable<TEntity> query = db;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
}
我的问题是,当我使用Get方法时,我宁愿它返回完整的对象图。延迟加载暂时关闭,但是为了急切加载我需要添加相关的包含,只有这样才能打败做通用存储库的对象。
我知道我可以使用find方法,但默认情况下使用get方法返回所有相关数据要快得多。
默认情况下我是如何获得所有(急切加载全部)的?
感谢。
答案 0 :(得分:4)
这是一个坏主意。特别是如果您计划进一步构建应用程序。这是解决性能瓶颈和OutOfMemory异常的道路。
我发现通用存储库也是反模式的。随着时间的推移,您将意识到您需要在Get
方法中添加越来越多的功能,最终它只会复制DbContext
的实现。
实际上,您当前的实现不会出于任何隔离目的。为什么不直接使用DbContext?
我建议转储Generic东西的想法,并使用小型Query类,只能以受控方式检索所需的实体,而不是每个人都能检索。看看this。
要回答您的问题,实体框架没有提供IncludeAll
的选项。你可以用反射进行破解,但我不打算在这里给出解决方案,因为这只是一种不好的做法。
答案 1 :(得分:1)
使用通用存储库模式,这是一个很好的方法,可以满足您的需求。希望它可以帮助某人,它易于使用,并且足够简单,可以包含在您的代码中。
IRepository.cs:
public interface IRepository<TEntity> where TEntity : class
{
IEnumerable<TEntity> GetAll(params Expression<Func<TEntity, object>>[] properties);
}
Repository.cs
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
private readonly DbSet<TEntity> _dbset;
public Repository(DbSet<TEntity> dbset)
{
_dbset = dbset;
}
public virtual IEnumerable<TEntity> GetAll(params Expression<Func<TEntity, object>>[] properties)
{
if (properties == null)
throw new ArgumentNullException(nameof(properties));
var query = _dbset as IQueryable<TEntity>; // _dbSet = dbContext.Set<TEntity>()
query = properties
.Aggregate(query, (current, property) => current.Include(property));
return query.AsNoTracking().ToList(); //readonly
}
}
解释如何使用的一些模型:
public class User
{
public int Id {get; set;}
public string Name {get; set;}
public List<Address> Address {get; set;}
public List<Cart> Carts {get; set;}
}
使用方法:
var repository = new Repository<User>();
var users = repository.GetAll(d => d.Address, d => d.Carts);
参考:Link