4

我有一个存储库模式,用于通过EF. 这是我的功能之一:

public IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate)
      where T : class
{
    return Context.Set<T>().Where<T>(predicate).AsQueryable<T>();
}

我想要做的是使用类似的东西来实现以下功能:

from c in Context.Customers
where !Context.Products.Any(p => p.ProductID == c.ProductID)
select c;

我需要它不仅适用于“客户”和“产品”,因此我需要一种通用方法,如我的原始存储库函数中所示。

- -编辑 - -

我想我追求的是这样的:

public IQueryable<T> Filter2<T, U>(Expression<Func<T,U, bool>> predicate)
    where T : class
    where U : class
{
    return ( Context.Set<T>().Where(
             !Context.Set<U>().Any(predicate)));
}

我希望像这样调用函数:

var result = _repository.Filter2<Products, Customers>((p, c) => p.ProductID == c.ProductID);

--编辑2--

更多背景信息:

我需要检查一个表中未在另一个表中引用的字段。我需要为许多不同的表执行此操作,并且访问实体框架需要通过存储库服务。我需要执行此操作的函数是通用的,因为我不想用特定于表的函数填充存储库服务。我的要求是传入一个表达式,该表达式定义了检查是如何完成的,以及一些引用表达式必须针对的两个表的方法。

4

1 回答 1

2

我不确定您为什么觉得需要一个与普通Filter方法相反的通用函数。您应该只将所需的任何谓词传递给一种Filter方法。应该没有理由不能像将“in”谓词传递给同一方法一样,将“not in”谓词传递给同一方法。由于它看起来像Customer并且Product是两个完全独立的实体(没有导航属性关系),您可能必须分别获取 ProductId 的集合才能在谓词中使用。

示例:( 在必要时填补 Repository API 中的空白)

var productRepository = new GenericRepository<Product>();
var productIds = productRepository.GetAll().Select(x => x.ProductId)

var customerRepository = new GenericRepository<Customer>();

// ProductId is IN Products
var customersInProducts = customerRepository.Filter(c => productIds.Contains(c.ProductId));

// ProductId is NOT IN Products
var customersNotInProducts = customerRepository.Filter(c => !productIds.Contains(c.ProductId));

在这种情况下,与 IN 和 NOT IN 的唯一区别是!.

于 2013-06-20T15:35:18.100 回答