我很难构建一个左连接查询,它执行类似这样的操作:
var Results =
from a in Db.Table1
join b in Db.Table2 on a.Id equals b.Id into c //IF b.Value2 == 1
from d in c.DefaultIfEmpty()
select new {Table1 = a};
我遇到的问题是我根本无法在“select”之前添加“where b.Value2 == 1”,因为这将排除b.Value2!= 1的所有连接行。
我想要发生的是,只有当b.Value2 == 1时才会加入列,如果没有,它将保留行(而不是将它们排除在上面描述的位置),但只是不加入两列。
我希望这是有道理的,有办法做到这一点,谢谢!
编辑:
Table1
ValueA=1,ValueB=1
ValueA=2,ValueB=2
Table2
ValueB=1,ValueC=1
ValueB=2,ValueC=2
Desired Result (joining on Table1.ValueB==Table2.ValueB Where Table2.ValueC == 2, still include this row, but just don't join it to Table2):
ValueA=1, ValueB=1, ValueC=null //ValueC=null because where Table2.ValueB==1,ValueC != 2
ValueA=2, ValueB=2, ValueC=2
答案 0 :(得分:1)
添加where,然后添加另一个仅适用于b.Value2!= 1的查询,合并两个查询?
答案 1 :(得分:1)
这应该可行,基本上创建一个虚拟var并加入它。问题是这不会对DB进行友好的下推操作。
var Results =
from a in Db.Table1
join b in Db.Table2 on
new { ID= a.Id, Bit = true }
equals
new { ID = b.Id, Bit = b.Value ==1 }
into c
from d in c.DefaultIfEmpty()
select new {
Table1 = a,
Table2= d //will be null if b.Value is not 1
};
答案 2 :(得分:1)
创建两个linq查询,它们将组成一个sql查询:
第一个查询将执行常规外连接
var partResult= from a in Db.Table1
join b in Db.Table2 on a.Id equals b.Id into c
from d in c.DefaultIfEmpty()
select new { Table1 = a, Table2=d};
第二个查询将从第一个查询中选择Table2为null或Table2.Id == 1
的所有条目var result = from obj in partResult
where (obj.Table2 == null || obj.Table2.Id == 2)
select obj.Table1;
当查询执行时,这将被组成一个select语句:
SELECT [t0].[Id]
FROM [dbo].[Table1] AS [t0]
LEFT OUTER JOIN (
SELECT 1 AS [test], [t1].[Id]
FROM [dbo].[Table2] AS [t1]
) AS [t2] ON [t0].[Id] = [t2].[Id]
WHERE ([t2].[test] IS NULL) OR ([t2].[Id] = 2)
如果表1有Ids 1,2,3,4,5,6且Table2有Ids 1,2,3,4结果将是1,5,6