【发布时间】:2020-03-06 00:55:24
【问题描述】:
我正在开发一个以足球为主题的 ASP.Net Core MVC Web 应用程序。我试图了解 EF Core,因为我之前所做的一切都是直接的 ADO.Net。
在我的数据库中,我有一个 Players 表、一个 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 的玩家。这是因为它正在使用 WHERE 子句创建以下 SQL,该子句过滤掉我想要保留的行...
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 中执行此操作,但我无法弄清楚如何使用 Linq 查询在 EF Core 中执行此操作。
更新:
感谢 Ivan Stoev,更正(和测试)的版本是:
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
}
【问题讨论】:
标签: linq entity-framework-core