Linq 中具有多个表和 LEFT OUTER JOIN 的复杂联接

Elt*_*ers 1 c# linq sql-server entity-framework-core

希望有人能通过这次加入为我指明正确的方向。我正在尝试将一些 SQL 转换为 Linq。我的 SQL 在几个内连接之后有一个左外连接。以下 SQL 产生所需的结果:

SELECT TOP(50) [t].[TagFriendlyName] AS [TagName], [t0].[timeStamp] AS [LastSeen], [l].[Name] AS [LocationName]
FROM [Tags] AS [t]
INNER JOIN [tag_reads] AS [t0] ON [t].[epc] = [t0].[epc]
INNER JOIN [ReaderData] AS [r] ON [t0].[ReaderDataId] = [r].[Id]
LEFT OUTER JOIN [Readers] AS [r0] ON [r].[mac_address] = [r0].[mac_address]
INNER JOIN [Locations] AS [l] on [t0].[antennaPort] = [l].[AntennaId] AND [r].[Id] = [l].[ReaderId]
GROUP BY [t].[TagFriendlyName], [t0].[timeStamp], [l].[Name]
ORDER BY [t0].[timeStamp] DESC 
Run Code Online (Sandbox Code Playgroud)

我的 Linq 代码如下,但我不知道如何正确插入左外连接。不知道如何引入需要 LEFT OUTER JOIN 的 Readers 表:

var query = (
from tags in db.Tags
join tagreads in db.tag_reads on tags.epc equals tagreads.epc
join readerdata in db.ReaderData on tagreads.ReaderDataId equals readerdata.Id
join readers in db.Readers on readerdata.mac_address equals readers.mac_address

group tags by new { tags.TagFriendlyName, timestamp = tagreads.timeStamp, readerdata.mac_address } into grp

select new CurrentStatus()
{
TagName = grp.Key.TagFriendlyName,
LastSeen = grp.Key.timestamp,
LocationName = grp.Key.mac_address
}
)
.OrderByDescending(o => o.LastSeen)
Run Code Online (Sandbox Code Playgroud)

根据我需要使用的文档DefaultIfEmpty(),但我不确定在哪里引入Readers表。

使用 EF Core 3.1.0。谢谢!

Arm*_*our 5

你应该Left Join这样申请:

join readers in db.Readers on readerdata.mac_address equals readers.mac_address into readersJ
from readers in readersJ.DefaultIfEmpty()
Run Code Online (Sandbox Code Playgroud)

完整代码:

var query = (
    from tags in db.Tags
    join tagreads in db.tag_reads on tags.epc equals tagreads.epc
    join readerdata in db.ReaderData on tagreads.ReaderDataId equals readerdata.Id
    join readers in db.Readers on readerdata.mac_address equals readers.mac_address into readersJ
    from readers in readersJ.DefaultIfEmpty()
    join locations in db.Locations 
        on new { ap = tagreads.antennaPort, rd = readerdata.Id }
        equals new { ap = locations.AntennaId, rd = locations.ReaderId }
    group tags by new { tags.TagFriendlyName, timestamp = tagreads.timeStamp, readerdata.mac_address } into grp

    select new CurrentStatus()
    {
        TagName = grp.Key.TagFriendlyName,
        LastSeen = grp.Key.timestamp,
        LocationName = grp.Key.mac_address
    }
)
.OrderByDescending(o => o.LastSeen)
Run Code Online (Sandbox Code Playgroud)