C# 需要一个接受两个表引用和一个表达式的通用存储库模式

C# 需要一个接受两个表引用和一个表达式的通用存储库模式,c#,entity-framework-4,repository-pattern,C#,Entity Framework 4,Repository Pattern,我有一个存储库模式,用于通过EF访问数据库。以下是我的一个功能: public IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate) where T : class { return Context.Set<T>().Where<T>(predicate).AsQueryable<T>(); } 我需要这样做,而不仅仅是为了

我有一个存储库模式,用于通过
EF
访问数据库。以下是我的一个功能:

public IQueryable<T> Filter<T>(Expression<Func<T, bool>> predicate)
      where T : class
{
    return Context.Set<T>().Where<T>(predicate).AsQueryable<T>();
}
我需要这样做,而不仅仅是为了“客户”和“产品”,因此我需要一种通用方法,如我的原始存储库功能所示

---编辑---

我想我在追求这样的东西:

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);
publicIQueryable过滤器2(表达式谓词)
T:在哪里上课
你在哪里上课
{
返回(Context.Set()。其中(
!Context.Set().Any(谓词));
}
我希望调用如下函数:

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);
var result=\u repository.Filter2((p,c)=>p.ProductID==c.ProductID);
--编辑2--

更多背景信息:


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

我不确定您为什么认为需要一个通用函数,该函数与正常的
过滤方法相反。您应该将所需的任何谓词传递给one
Filter
方法。没有理由不能以与向同一方法传递“in”谓词相同的方式传递“notin”谓词。由于它看起来像是
Customer
Product
是两个完全独立的实体(没有导航属性关系),因此您可能必须分别获取ProductID集合才能在谓词中使用

示例:(必要时填补存储库API中的空白)

var-productRepository=new-GenericRepository();
var productIds=productRepository.GetAll().Select(x=>x.ProductId)
var customerRepository=new genericpository();
//ProductId在Products中
var customersInProducts=customerRepository.Filter(c=>productIds.Contains(c.ProductId));
//ProductId不在产品中
var customersNotInProducts=customerRepository.Filter(c=>!productIds.Contains(c.ProductId));

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

为什么不使用相同的函数,但对谓词求反?我不知道你的意思。你能为你需要的功能做些模型吗?它不需要使用正确的语法。我很难在您的特定示例中看到这方面的用例-为什么不直接执行
p.ProductID!=c、 ProductID
?这是一个非常奇怪和不直观的例子。为什么客户会有一个
ProductID
?马丁·史密斯:我对ProductID有点输入错误。我只是想展示一个检查两个表之间链接的示例。如果你看看我的问题(第二个编辑部分),我会尝试更清楚地解释我的要求。我的要求是传入一个表达式并对两个表运行该表达式。我不想硬编码表定义,所以我想使用泛型,因此我的问题是。不幸的是,我最初的问题可能没有用最好的例子来解释我的表达式,因为每个人似乎都认为这个问题是关于有一个函数来做普通滤波器的逆运算。我确信,如果不沿着表达式树路线走下去,我想做的事情就无法完成。@Retrocoder我的解决方案不硬编码表定义,而是使用通用存储库方法。您可以将
Product
Customer
替换为您想要的任何两种类型的实体,只要这些实体有两个兼容的属性,如本例中的
ProductId
,那么它仍然可以工作。我知道您希望以某种方式进一步泛化此逻辑,并将其封装在您的repository类中,但由于存储库通常与实体有1对1的关联,您可能会发现,要做到这一点并不容易,而且会非常尴尬。虽然我从一个存储库模式开始,使用CRUD,我想做的更改使它更像一个通用的数据抽象层。经过一些实验,很明显我想做的事情,即将数据库访问代码保存在一个地方,是行不通的。我希望对存储库进行一次调用以返回结果,但现在我改变了方法。现在,我通过对存储库的两个调用和调用类中的一行Linq来完成我需要做的事情。Linq正在处理IQueryables,因此我将数据访问权从我的veiwmodel类中移除。我接受了您的回答,因为它几乎满足了要求,而且我的问题措辞不太好(我在回家之前发送了它)。