我们有一个多层应用程序,其中所有存储库都基于(自行开发的)GenericRepository基类(其中T是模型中的实体),它公开了诸如GetContext(),GetObjectSet()之类的方法。等等。我们允许从此继承的存储库访问上下文,因为它们需要调用Include(),因为我们正在通过WCF服务传递数据,因此需要急切地加载所有相关实体。
我们所有的实体都实现了一个具有Active bool属性的接口,我们要做的是拦截查询的执行,并对Active属性进行过滤,以便任何查询只返回设置为真。
可以这样做吗?在基于EF构建的Lightswitch中,您可以捕获的事件会在查询执行的深度中被触发,并允许您执行此类过滤。我在EF本身找不到允许这样做的任何内容。
任何想法?感谢
答案 0 :(得分:1)
我能想到的最佳方式是让您的存储库方法接受表达式(即Expression<Func<T, bool>> predicate
)。这样,您可以在实际存储库本身中执行所有查询(因此不允许以任何方式访问数据层逻辑的客户端代码),在从存储库方法返回之前可以向其添加Where
只抓住那些活跃的。
我使用的这种风格的一个例子如下:
public IQueryable<T> Grab(Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
其中DbSet是您尝试查询的实际表。这样你可以在它的末尾添加.Where(x => x.Active)
,让它不对数据库执行(谢谢,延迟执行!)但仍然可以获得你正在寻找的确切记录。
答案 1 :(得分:1)
在EF 5中,Include
是IQueryable
上的扩展方法,因此您可以这样做:
var query = dbSet.Where( o => o.IsActive ).Include( ... )
这意味着,您不必从通用存储库返回DbSet<T>
- 应该可以返回IQueryable<T>
。
如果这符合您的要求,您可以在通用存储库方法中添加Where
子句:
partial class GenericRepository<T>
{
public IQueryable<T> Query( bool includeInactive = false )
{
return ctx.Set<T>().Where( o => includeInactive || o.IsActive );
}
}