LINQ中的条件连接
本文关键字:连接 条件 LINQ | 更新日期: 2023-09-27 18:11:28
所以我有一个小问题与linq。我想要一个连接是OUTER join还是INNER join,这取决于是否在表
上过滤值。外连接:
var query = (from tblA in dc.tblA
join tblB in GetMyTable() on tblA.Ref equals tblB.RefA into joinedTblB
from tblB in joinedTblB.DefaultIfEmpty()
select tblA);
内连接:
var query = (from tblA in dc.tblA
join tblB in GetMyTable() on tblA.Ref equals tblB.RefA into joinedTblB
from tblB in joinedTblB
select tblA);
我想要的是将它们组合在同一个查询中,并通过检查某些条件来执行OUTER JOIN或INNER JOIN,就像这样:
var query = (from tblA in dc.tblA
join tblB in GetMyTable() on tblA.Ref equals tblB.RefA into joinedTblB
from tblNEWB in ((checkCondition==false) ? joinedTblB.DefaultIfEmpty() : joinedTblB)
select new {
tblA.ValueA,
tblNEWB.ValueB
});
我希望这将工作,但我得到一个错误说"InvalidOperationException:成员访问"系统。在类型"System.Collections.Generic"上,"tblB"的字符串值不合法。IEnumerable 1 (tblB)"
我错过了什么吗?
:
我想要的是一个外部连接,但是当在tlbB上设置条件时,linq没有产生我希望的查询。打开SQL Profiler会得到如下查询:
LEFT OUTER JOIN tblB ON tblA.Ref = tblB.REfA AND tlbB.Key = '100'
而正确的查询应该是:
LEFT OUTER JOIN tblB ON tblA.Ref = tblB.RefA
WHERE tblB.Key = '100'
这样做的原因是我的GetMyTable-function设置了连接表的条件
我想要的是将它们组合在同一个查询中,并通过检查某些条件来执行OUTER JOIN或INNER JOIN
得到你想要的第一步是认识到两个不同的sql语句是必需的。LinqToSql不会将您的条件发送到数据库中,因此数据库可以根据值计算出应该发生哪种类型的连接。
第二步,是切换到方法语法。这种语法更容易被条件组合。
第三步,放弃匿名类型。您必须做一些不愉快的事情来声明查询构造所需的变量。只要用你需要的属性创建一个类型,然后使用它。
public class AandB
{
public A TheA {get;set;}
public B TheB {get;set;}
}
IQueryable<A> queryA = dc.TblA.AsQueryable();
IQueryable<AandB> queryAandB = null;
if (checkCondition)
{
//inner join
queryAandB = queryA
.Join(
GetMyTable(),
a => a.Ref, b => b.RefA,
(a, b) => new AandB() {TheA = a, TheB = b}
);
}
else
{
// left join
queryAandB = queryA
.GroupJoin(
GetMyTable(),
a => a.Ref, b => b.RefA,
(a, g) => new {a, g}
)
.SelectMany(
x => x.g.DefaultIfEmpty(),
(x, b) => new AandB(){TheA = x.a, TheB = b}
);
}
List<AandB> results = queryAandB.ToList();
如果左连接是你需要的,你的第一个查询应该做的工作
(from tblA in dc.tblA
join tblB in GetMyTable() on tblA.Ref equals tblB.RefA into joinedTblB
from tblB in joinedTblB.DefaultIfEmpty()
select new {tblAField = tblA.F1 , tblBField = tblB == null ? null : tblB.F2);
内部连接查询如下所示
(from tblA in dc.tblA
join tblB in GetMyTable() on tblA.Ref equals tblB.RefA
select new { A = tblA, B = tblB } );
我不确定这是否正是你正在寻找的,但它应该接近。
var query = from rowA in db.tblA
join rowB in db.tblB on rowA.idB equals rowB.idB into b
from item in b.DefaultIfEmpty()
select new
{
rowA.ValueA,
rowB.ValueB
};