在 Linq Query 中传递引用两个连接记录的选择查询
Passing selection query referencing two joined records in Linq Query
假设我 table 调用了 CustomerTransaction,我可以将选择标准传递给
这样的例程
void GetData1(Expression<Func<CustomerTransaction, bool>> selection)
{
CustomerTransaction.Where(selection).Take(2).Dump();
}
使用类似
的代码
Expression<Func<CustomerTransaction, bool>> query = r => (r.CustomerID == 1);
GetData1(query);
但是,我希望能够从这个 table 中加入两条记录,并传入一个参考两个 table 的选择标准。
例如下面会编译(在LinqPad中),
void GetData2(Expression<Func<Tuple<CustomerTransaction,CustomerTransaction>, bool>> selection)
{
var baseQuery = (from ct1 in CustomerTransaction
join ct2 in CustomerTransaction on ct1.MasterTransactionID equals ct2.RelatedTransactionID
select new Tuple<CustomerTransaction, CustomerTransaction> ( ct1, ct2)) ;
var query = baseQuery.Where(selection).Dump();
}
Expression<Func<Tuple<CustomerTransaction,CustomerTransaction>, bool>> query2 =
r => r.Item1.CustomerID != r.Item2.CustomerID;
GetData2(query2);
但是,它不会 运行 因为 SQL 不处理元组。
如果我试图以某种 SQL 会理解的方式来写这篇文章,那么我将无法通过选择标准,因为我不知道选择的类型
例如
void GetData3( ??? selection)
{
var baseQuery = (from ct1 in CustomerTransaction
join ct2 in CustomerTransaction on ct1.MasterTransactionID equals ct2.RelatedTransactionID
select new { Customer1 = ct1.CustomerID, Customer2 = ct2.CustomerID } );
baseQuery.Where(selection).Dump();
}
显然真正的查询更复杂,它们是多个选择条件,我试图避免对每个可能的部分条件重复查询。
有什么解决办法吗?
您可以创建一个明确的 class 来表示您的 join
结果,并在该 class:
上创建您的 Where
表达式
public class CT2 {
public CustomerTransaction ct1;
public CustomerTransaction ct2;
}
然后您可以在查询中使用 class 和 Where
表达式:
void GetData2(Expression<Func<CT2, bool>> selection) {
var baseQuery = from ct1 in db.CustomerTransaction
join ct2 in db.CustomerTransaction on ct1.MasterTransactionID equals ct2.RelatedTransactionID
select new CT2 { ct1 = ct1, ct2 = ct2 };
var query = baseQuery.Where(selection).Dump();
}
Expression<Func<CT2, bool>> query2 =
r => r.ct1.CustomerID != r.ct2.CustomerID;
GetData2(query2);
假设我 table 调用了 CustomerTransaction,我可以将选择标准传递给
这样的例程void GetData1(Expression<Func<CustomerTransaction, bool>> selection)
{
CustomerTransaction.Where(selection).Take(2).Dump();
}
使用类似
的代码Expression<Func<CustomerTransaction, bool>> query = r => (r.CustomerID == 1);
GetData1(query);
但是,我希望能够从这个 table 中加入两条记录,并传入一个参考两个 table 的选择标准。
例如下面会编译(在LinqPad中),
void GetData2(Expression<Func<Tuple<CustomerTransaction,CustomerTransaction>, bool>> selection)
{
var baseQuery = (from ct1 in CustomerTransaction
join ct2 in CustomerTransaction on ct1.MasterTransactionID equals ct2.RelatedTransactionID
select new Tuple<CustomerTransaction, CustomerTransaction> ( ct1, ct2)) ;
var query = baseQuery.Where(selection).Dump();
}
Expression<Func<Tuple<CustomerTransaction,CustomerTransaction>, bool>> query2 =
r => r.Item1.CustomerID != r.Item2.CustomerID;
GetData2(query2);
但是,它不会 运行 因为 SQL 不处理元组。
如果我试图以某种 SQL 会理解的方式来写这篇文章,那么我将无法通过选择标准,因为我不知道选择的类型
例如
void GetData3( ??? selection)
{
var baseQuery = (from ct1 in CustomerTransaction
join ct2 in CustomerTransaction on ct1.MasterTransactionID equals ct2.RelatedTransactionID
select new { Customer1 = ct1.CustomerID, Customer2 = ct2.CustomerID } );
baseQuery.Where(selection).Dump();
}
显然真正的查询更复杂,它们是多个选择条件,我试图避免对每个可能的部分条件重复查询。
有什么解决办法吗?
您可以创建一个明确的 class 来表示您的 join
结果,并在该 class:
Where
表达式
public class CT2 {
public CustomerTransaction ct1;
public CustomerTransaction ct2;
}
然后您可以在查询中使用 class 和 Where
表达式:
void GetData2(Expression<Func<CT2, bool>> selection) {
var baseQuery = from ct1 in db.CustomerTransaction
join ct2 in db.CustomerTransaction on ct1.MasterTransactionID equals ct2.RelatedTransactionID
select new CT2 { ct1 = ct1, ct2 = ct2 };
var query = baseQuery.Where(selection).Dump();
}
Expression<Func<CT2, bool>> query2 =
r => r.ct1.CustomerID != r.ct2.CustomerID;
GetData2(query2);