EF Core 3中linq查询的外部联接不工作

EF Core 3中linq查询的外部联接不工作,linq,entity-framework-core,Linq,Entity Framework Core,我正在开发一个以足球为主题的ASP.Net核心MVC web应用程序。我正试图了解EF Core,因为我之前所做的一切都是直接的ADO.Net 在我的数据库中,我有一个用于玩家的表、一个用于匹配事件的表和一个用于创建多对多关系的联接表,称为PlayerMatcheEvents 我正试图将所有球员连同他们在某一特定赛事赛事中的角色召集到一起,包括没有参与该赛事的球员。换句话说,一个外部连接 我所有的研究都得出了相同的解决方案,即在临时变量中使用组联接和使用DefaultIfEmpty(),但我就

我正在开发一个以足球为主题的ASP.Net核心MVC web应用程序。我正试图了解EF Core,因为我之前所做的一切都是直接的ADO.Net

在我的数据库中,我有一个用于玩家的表、一个用于匹配事件的表和一个用于创建多对多关系的联接表,称为PlayerMatcheEvents

我正试图将所有球员连同他们在某一特定赛事赛事中的角色召集到一起,包括没有参与该赛事的球员。换句话说,一个外部连接

我所有的研究都得出了相同的解决方案,即在临时变量中使用组联接和使用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条件放在join上而不是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
}

将MatchEventID条件放入联接的标准LINQ方法是,例如


在EF Core中,我们通常使用导航属性,并且在执行联接之前,我们还可以将外部谓词推送到右侧子查询中,但是上面的LINQ手动联接与SQL联接最接近。

谢谢,这就成功了(虽然为了避免错误CS1941,我不得不在右侧指定相同的名称:join子句中的一个表达式的类型不正确。对“GroupJoin”的调用中的类型推断失败,所以现在我有了:在new{PlayerId=p.ID,MatchEventID=2}上等于new{PlayerId=pme.PlayerId,MatchEventID=pme.MatchEventID})。我必须看看如何使用导航属性-就像我说的,这对我来说是全新的!这只是我在代码中输入了左侧属性名(
PlayerId
),而不是
PlayerId
)。这个想法当然是匹配右侧属性名,您以不同的方式解决了这个问题(不太简洁,但仍然有效)对,我怎么没看到?谢谢。
on new { PlayerID = p.ID, MatchEventID = 2 } equals new { pme.PlayerID, pme.MatchEventID }