C# 具有多个或多个条件的EF core联接

C# 具有多个或多个条件的EF core联接,c#,sql-server,linq,c#-6.0,ef-core-2.1,C#,Sql Server,Linq,C# 6.0,Ef Core 2.1,我想将此sql查询转换为linq: select * from A a join B b on ( (a.level1= b.PerimeterID and b.PerimeterLevelID = 1) OR (a.level2= b.PerimeterID and b.PerimeterLevelID = 2) OR (a.level3= b.PerimeterID and b.PerimeterLevelID = 3)

我想将此sql查询转换为linq:

select * from  A a
join B b on (    (a.level1= b.PerimeterID and  b.PerimeterLevelID = 1)
              OR (a.level2= b.PerimeterID and  b.PerimeterLevelID = 2)
              OR (a.level3= b.PerimeterID and  b.PerimeterLevelID = 3)
            )
我尝试的是:

from a in A
join b in B on new {PerimeterID = a.level1, PerimeterLevelID = 1 } equals new { b.PerimeterID, b.PerimeterLevelID }
where (a.level2 == b.PerimeterID && b.PerimeterLevelID == 2) ||
      (a.level3 == b.PerimeterID && b.PerimeterLevelID == 3)
它将生成以下sql查询:

select * from  A a
join B b on (a.level1= b.PerimeterID and  b.PerimeterLevelID = 1)
where (a.level2= b.PerimeterID and  b.PerimeterLevelID = 2)
       OR (a.level3= b.PerimeterID and  b.PerimeterLevelID = 3))
我也尝试过,但它无法转换或转换为linq

SQL无法转换为LINQ:或


转换此sql查询所需的操作

您可以尝试使用
DefaultIfEmpty()
。使用此命令,联接的行为将类似于左联接

from a in A
from b in B.DefaultIfempty()
where (   (a.level1== b.PerimeterID &&  b.PerimeterLevelID == 1)
       || (a.level2== b.PerimeterID &&  b.PerimeterLevelID == 2)
       || (a.level3== b.PerimeterID &&  b.PerimeterLevelID == 3))

内部联接相当于过滤的交叉联接。那你呢

from a in A
from b in B 
where (a.level1 == b.PerimeterID && b.PerimeterLevelID == 1) ||
      (a.level2 == b.PerimeterID && b.PerimeterLevelID == 2) ||
      (a.level3 == b.PerimeterID && b.PerimeterLevelID == 3)
select new {a,b};

我认为这个查询会有所帮助

var query = from a in context.A
            join b1 in context.B
                on new { Perimeter = a.level1, LevelID = 1 }
                equals new { Perimeter = b1.PerimeterID, LevelID = b1.PerimeterLevelID }
            join b2 in context.B
                on new { Perimeter = a.level2, LevelID = 2 }
                equals new { Perimeter = b2.PerimeterID, LevelID = b2.PerimeterLevelID }
            join b3 in context.B
                on new { Perimeter = a.level3, LevelID = 3 }
                equals new { Perimeter = b3.PerimeterID, LevelID = b3.PerimeterLevelID }
            select new
            {
                a,
                b1,
                b2,
                b3
            };

DefaultIfEmpty
对原始海报有什么作用?他抱怨的不是没有得到记录,而是生成的SQL不是他想要的。@OmarAMEZOUG我修复了代码。抱歉,我似乎需要睡眠:)我尝试了这个解决方案,但它生成了一个交叉连接,我希望避免,因为我有一个巨大的表,性能问题一个带有WHERE子句的交叉连接在语义和(至少在SQL Server中)性能方面与内部连接相同。