【发布时间】:2021-09-15 16:19:12
【问题描述】:
最近我将Navigation Properties 添加到没有任何FK 的EF Core 项目中,以便在尽可能多的查询中使用Include 而不是Join,但我发现无论是sintax几乎所有查询都不适合我的需求(需要拆分为多个查询),或者我遗漏了一些东西,所以我举个例子,我想知道,使用Navigation Properties 你会如何获取特定 dayType 的所有 Stops 及其 Line 列表?:
| Stop |
|---|
| stopId |
| Point |
|---|
| pointId |
| stopId? |
| routeId |
| Route |
|---|
| routeId |
| serviceDetailId |
| ServiceDetail |
|---|
| serviceDetailId |
| serviceHeaderId |
| ServiceHeaderDay |
|---|
| serviceHeaderDayId |
| serviceHeaderId |
| dayType |
| ServiceHeader |
|---|
| serviceHeaderId |
| lineId |
| Line |
|---|
| lineId |
使用Join 的当前工作查询,我想使用Include 进行翻译:
var query = (await context.Stop
.Join(
context.Point,
(stop) => stop.stopId,
(point) => point.stopId,
(stop, point) => new { Stop = stop, Point = point })
.Join(
context.Route,
(join) => join.Point.routeId,
(route) => route.routeId,
(join, route) => new { Stop = join.Stop, Route = route })
.Join(
context.ServiceDetail,
(join) => join.Route.routeId,
(serviceDetail) => serviceDetail.routeId,
(join, serviceDetail) => new { Stop = join.Stop, ServiceDetail = serviceDetail })
.Join(
context.ServiceHeader,
(join) => join.ServiceDetail.serviceHeaderId,
(serviceHeader) => serviceHeader.serviceHeaderId,
(join, serviceHeader) => new { Stop = join.Stop, ServiceHeader = serviceHeader })
.Join(
context.ServiceHeaderDay,
(join) => join.ServiceHeader.serviceHeaderId,
(serviceHeaderDay) => serviceHeaderDay.serviceHeaderId,
(join, serviceHeaderDay) => new { Stop = join.Stop, ServiceHeader = join.ServiceHeader, ServiceHeaderDay = serviceHeaderDay })
.Join(
context.Line,
(join) => join.ServiceHeader.lineId,
(line) => line.lineId,
(join, line) => new { Stop = join.Stop, ServiceHeaderDay = join.ServiceHeaderDay, Line = line })
.Where(e => e.ServiceHeaderDay.DayType == "L")
.Select(e => new { Stop = e.Stop, Line = e.Line })
.Distinct();
.ToListAsync())
// The query ends here, this next step is just grouping by Stops and inserting each Line list into them.
.GroupBy(e => e.Stop.stopId)
.Select(e =>
{
var stop = e.First().Stop;
stop.Lines = e.Select(e => e.Line).ToList();
return stop;
})
使用Include 进行的失败尝试之一:
context.Stop
.Include(e => e.Points)
.ThenInclude(e => e.Route)
.ThenInclude(e => e.ServiceDetail)
.ThenInclude(e => e.ServiceHeader)
.ThenInclude(e => e.ServiceHeaderDay
Where(e => e.DayType = "L")
// Now I need to Include Line from ServiceHeader, but this is a of type ServiceHeaderDay
// and I think you can't use anonymous objects to carry all the tables you just include
// so I found people repeating the includes like this:
.Include(e => e.Point)
.ThenInclude(e => e.Route)
.ThenInclude(e => e.ServiceDetail)
.ThenInclude(e => e.ServiceHeader)
.ThenInclude(e => e.Line)
// This doesn't seem to work, but also how would be the select to get the Stops with all
// the lines for each Stop here?
.Select(e => ?)
【问题讨论】:
标签: linq join entity-framework-core include navigation-properties