c# – 需要一个采用两个表引用和表达式的通用存储库模式

我有一个存储库模式,我用它通过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);

–EDIT 2–

更多背景信息:

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

最佳答案 我不确定为什么你觉得需要一个泛型函数来执行普通Filter方法的反转.您应该将所需的谓词传递给一个Filter方法.你没有理由不能像传入“in”谓词一样传入“not in”谓词.由于Customer和Product看起来像是两个完全独立的实体(没有导航属性关系),因此您可能必须单独获取ProductIds的集合才能在谓词中使用.

示例:(必要时填写存储库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的唯一区别是!

点赞