конвертировать SQL в LINQ не работает

Я хочу преобразовать этот код SQL в LINQ. Вот мой код SQL:

SELECT Rooms.RoomName AS RoomNo, Beds.BedName AS Beds, Rooms.RoomType, ISNULL(CheckIn.CheckIntatus,'') AS Status 
FROM CheckIn
INNER JOIN GuestBeds ON CheckIn.GuestBedId = GuestBeds.Id
AND (CheckIn.CheckInStatus = 1 OR CheckIn.CheckIntatus = 2 OR CheckIn.CheckSIntatus = 3) 
RIGHT JOIN Beds ON GuestBeds.BedId = Beds.Id
INNER JOIN Rooms ON Beds.RoomId = Rooms.Id
LEFT JOIN Guests ON CheckIn.GuestId = Guests.Id
WHERE Beds.Active = 1 AND Rooms.Active = 1
ORDER BY RoomName, Beds

Он работает хорошо, что означает, что он показывает все RoomName с CheckInStatus. Если комнаты нет в таблице CheckIn, ot вернет статус Null. Итак, я хочу преобразовать код в LINQ. Итак, вот мой код LINQ:

from b in Beds 
join w in Rooms on b.RoomsId equals w.Id
where (a.CheckInStatus == 3 || a.CheckInStatus == 1 || a.CheckInStatus == 2)
join p in GuestBeds on b.Id equals p.BedId
join a in CheckIn on p.Id equals a.GuestBedId 
join t in Guests on a.GuestId equals t.Id
where b.Active == true && w.Active == true
orderby w.RoomName
select new
{
    RoomName = w.RoomName,
    BedName = b.BedName,
    Status = a.CheckInStatus
}

Это не сработало, как первый код. Он показывает только те данные, которые содержат CheckInStatus. Я хочу, чтобы он показывал все RoomName внутри базы данных Room.


person yusry    schedule 25.01.2018    source источник
comment
Похоже, ваш SQL использует соединения LEFT и RIGHT, но ваш LINQ не принимает это во внимание. Посмотрите, поможет ли это: stackoverflow.com/questions /4497086/   -  person Randy Slavey    schedule 25.01.2018
comment
Есть ли какая-то причина, по которой вы не скопировали/вставили свой SQL? В нем есть ошибки...   -  person NetMage    schedule 26.01.2018


Ответы (1)


Обычно я публикую некоторые правила преобразования SQL в LINQ, но это достаточно сложно, и я думаю, что мне нужно будет создать новые правила. Я закомментировал ссылки на Guests, потому что как LEFT JOIN это не имеет отношения к ответу.

Вытащите WHERE из отдельных таблиц и сделайте из них подзапросы:

var ActiveBeds = Beds.Where(b => b.Active == 1);
var ActiveRooms = Rooms.Where(r => r.Active == 1);

В LINQ RIGHT JOIN необходимо выполнить, перевернув соединение, чтобы оно стало левым соединением, поэтому мы создадим две стороны как подзапросы.

Слева от RIGHT JOIN:

Преобразуйте условия JOIN, которые не являются частью эквивалентного соединения, в предложение LINQ where в соответствующих таблицах (в качестве альтернативы это может быть подзапрос, как указано выше). LEFT JOIN становится фразой LINQ join/from ... DefaultIfEmpty(), но, как отмечалось выше, в ней нет необходимости.

var CheckInsGuestBedsGuests = from c in CheckIn
                              where (c.CheckInStatus == 1 || c.CheckInStatus == 2 || c.CheckInStatus == 3)
                              join gb in GuestBeds on c.GuestBedId equals gb.Id
                              //join g in Guests on c.GuestId equals g.Id into gj
                              //from g in gj.DefaultIfEmpty()
                              select new { c, gb /*, g */ };

Справа от RIGHT JOIN:

Другая сторона RIGHT JOIN включает INNER JOIN, поэтому соедините их вместе в подзапросе:

var ActiveBedsRooms = from b in ActiveBeds
                      join r in ActiveRooms on b.RoomId equals r.Id
                      select new { b, r };

Наконец, переверните подзапросы, чтобы создать левое соединение, используя ту же идиому, что и выше:

var ans = from br in ActiveBedsRooms
          join cgbg in CheckInsGuestBedsGuests on br.b.Id equals cgbg.gb.BedId into cgbgj
          from cgbg in cgbgj.DefaultIfEmpty()
          select new {
              RoomNo = br.r.RoomName,
              Beds = br.b.BedName,
              br.r.RoomType,
              Status = cgbg.c.CheckInStatus
          };

ПРИМЕЧАНИЕ. Если вы не использовали LINQ to SQL, выражение Status потерпит неудачу, если cgbg равно null, и вам потребуется

              Status = cgbg?.c.CheckInStatus

но, к сожалению, LINQ to SQL/EF еще не обрабатывает нулевые условные операторы.

Кстати, хороший вопрос - навевает воспоминания о том, когда я писал программное обеспечение для стойки регистрации отеля :)

person NetMage    schedule 25.01.2018