Я занимаюсь разработкой футбольного приложения ASP. Net Core MVC. Я пытаюсь разобраться в EF Core, поскольку все, что я делал ранее, было прямым ADO. Net.
В моей базе данных есть таблица для игроков, таблица для MatchEvents и таблица соединений для создания отношения «многие ко многим», которая называется PlayerMatchEvents.

Я пытаюсь получить ВСЕХ Игроков вместе с их ролью в MatchEvent для конкретного MatchEvent, включая Игроков, которые не участвуют в этом матче. Другими словами, внешнее объединение.
Все мои исследования приводят к одному и тому же решению: объединение группы во временную переменную и использование DefaultIfEmpty (), но я просто не могу заставить его работать!
Код, с которым я сейчас работаю:
from p in Players
join pme in PlayerMatchEvents
on p.ID equals pme.PlayerID
into temp
from t in temp.DefaultIfEmpty() where t.MatchEventID ==2
select new
{
PlayerFirstName = p.FirstName,
PlayerLastName = p.LastName,
Attendance = t == null ? null : t.PlayerMatchAttendanceDetail.Description
}
Приведенный выше код дает те же результаты, что и внутреннее соединение - т.е. возвращаются только те игроки, которые уже связаны с MatchEvent 2. Это потому, что он создает следующее SQL с предложением WHERE, отфильтровывающим строки, которые я хочу сохранить ...
SELECT [p].[FirstName] AS [PlayerFirstName], [p].[LastName] AS [PlayerLastName], [p1].[Description] AS [Attendance]
FROM [Players] AS [p]
LEFT JOIN [PlayerMatchEvents] AS [p0] ON [p].[ID] = [p0].[PlayerID]
LEFT JOIN [PlayerMatchAttendanceDetail] AS [p1] ON [p0].[PlayerMatchAttendanceDetailID] = [p1].[PlayerMatchAttendanceDetailID]
WHERE [p0].[MatchEventID] = 2
GO
Я пытаюсь достичь EF-эквивалента этого:
SELECT [p].[FirstName] AS [PlayerFirstName], [p].[LastName] AS [PlayerLastName], [p1].[Description] AS [Attendance]
FROM [Players] AS [p]
LEFT JOIN [PlayerMatchEvents] AS [p0] ON [p].[ID] = [p0].[PlayerID] AND [p0].[MatchEventID] = 2
LEFT JOIN [PlayerMatchAttendanceDetail] AS [p1] ON [p0].[PlayerMatchAttendanceDetailID] = [p1].[PlayerMatchAttendanceDetailID]
GO
Помещение критериев MatchEventID в объединение вместо предложения WHERE возвращает ВСЕХ игроков, включая тех, кто не связан с MatchEvent, чего я и хочу. Я могу сделать это в SQL, но я просто не могу понять, как это сделать в EF Core с запросами Linq.
Обновление:
Спасибо Ивану Стоев, исправленная (и протестированная) версия:
from p in Players
join pme in PlayerMatchEvents
on new { PlayerId = p.ID, MatchEventID = 2 } equals new { PlayerId = pme.PlayerID, MatchEventID = pme.MatchEventID }
into temp
from t in temp.DefaultIfEmpty()
select new
{
PlayerFirstName = p.FirstName,
PlayerLastName = p.LastName,
Attendance = t == null ? null : t.PlayerMatchAttendanceDetail.Description
}