Соединение ядра EF с несколькими условиями ИЛИ - PullRequest
0 голосов
/ 06 января 2019

Я хочу преобразовать этот 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))

Я также пытался Linqer , но он не может преобразовать ИЛИ в linq

SQL не может быть преобразован в LINQ: ИЛИ

что мне нужно сделать, чтобы преобразовать этот SQL-запрос

Ответы [ 3 ]

0 голосов
/ 06 января 2019

Внутреннее соединение эквивалентно фильтрованному перекрестному соединению. Так как насчет

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};

0 голосов
/ 06 января 2019

Я думаю, что этот запрос поможет

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
            };
0 голосов
/ 06 января 2019

вы можете попробовать с 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))
...