0

我们有一个多层应用程序,其中所有存储库都基于(本土)GenericRepository 基类(其中 T 是模型中的实体),它公开了 GetContext()、GetObjectSet() 等方法. 我们允许从这里继承的存储库访问上下文,因为它们需要调用 Include(),因为我们通过 WCF 服务向上传递数据,因此需要急切地加载所有相关实体。

我们所有的实体都实现了一个具有 Active bool 属性的接口,我们想要做的是拦截查询的执行,并对 Active 属性进行过滤,以便任何查询只返回设置为 true 的实体。

这可以做到吗?在基于 EF 构建的 Lightswitch 中,您可以捕获一个事件,该事件在查询执行的深度被触发,并允许您执行此类过滤。我在 EF 本身中找不到任何允许这样做的东西。

有人有什么想法吗?谢谢

4

2 回答 2

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)到它的末尾,让它尚未对数据库执行(谢谢,延迟执行!),但仍然可以获得您正在寻找的确切记录。

于 2013-02-14T16:39:56.457 回答
1

在 EF 5 中,Include是 上的扩展方法IQueryable,因此您可以这样做:

var query = dbSet.Where( o => o.IsActive ).Include( ... )

这意味着,您不必DbSet<T>从通用存储库中返回 a - 应该可以返回IQueryable<T>.

如果这符合您的要求,您可以Where在通用存储库方法中添加一个子句:

partial class GenericRepository<T>
{
  public IQueryable<T> Query( bool includeInactive = false )
  {
    return ctx.Set<T>().Where( o => includeInactive || o.IsActive );
  }
}
于 2013-02-14T16:51:09.377 回答