LINQ从联接表中选择,其中同一外键具有两个不同ID的记录

时间:2019-06-13 05:43:23

标签: c# entity-framework linq-to-entities

好的,所以标题有点让人困惑。基本上我有那三个表:

Line

id | Name
---------
1  | "A-B"
2  | "A-D"


Stop

id | Name
---------
1  | A
2  | B
3  | C
4  | D

LineStop

Id | LineId | StopId | Order
----------------------------
1  | 1      | 1      | 0
2  | 1      | 2      | 1
3  | 2      | 1      | 0
4  | 2      | 2      | 1
5  | 2      | 3      | 3
4  | 2      | 4      | 4

因此,这是我要进行个人改进的某种公交车票系统。

作为输入,我得到了出发StopId(Stop.Id)和到达StopId(Stop.Id)。我想选择所有在其路线中具有这两个停靠点的行(这意味着在LineSop表的同一LineId中,我将同时拥有出发和到达停靠点的记录,最终我会还希望考虑Order列,该列告诉公交车通过这些停靠点的顺序,因为即使线路上有我感兴趣的两个停靠点,如果它们按相反的顺序排列,我仍然不会感兴趣。

我知道显示到目前为止已经完成的工作非常可取,但是我在哪里似乎是关键因素的条件下挣扎。由于某种原因,我决定将LineLineStop一起加入:

var lines = _context.Lines.Join(
            _context.LineStop,
            line => line.Id,
            lineStop => lineStop.LineId,
            (line, lineStop) => lineStop)

但是,..我需要检查在LineId表中是否有相同的LineStop记录,并且记录的开头和结尾为StopId,最终,当我发现这样的记录时, StopId的i顺序比结束的StopId顺序小。

1 个答案:

答案 0 :(得分:0)

我希望这可以帮助您:

首先,我从旅行者那里得到了旅行:“我想从Stop:2转到Stop:4”。 一旦知道两条停靠点的线,我便建立停靠点及其顺序。

var lines = new List<Line>() 
{ 
    new Line() { Id = 1, Name = "A-B" },
    new Line() { Id = 2, Name = "A-D" }
}; 

var stops = new List<Stop>() {
    new Stop() { Id = 1, Name = "A" },
    new Stop() { Id = 2, Name = "B" },
    new Stop() { Id = 3, Name = "C" },
    new Stop() { Id = 4, Name = "D" }
};

var lineStops = new List<LineStop>() 
{
    new LineStop() { Id = 1, LineId = 1, StopId = 1, Order = 0 },
    new LineStop() { Id = 2, LineId = 1, StopId = 2, Order = 1 },
    new LineStop() { Id = 3, LineId = 2, StopId = 1, Order = 0 },
    new LineStop() { Id = 4, LineId = 2, StopId = 2, Order = 1 },
    new LineStop() { Id = 5, LineId = 2, StopId = 3, Order = 3 },
    new LineStop() { Id = 4, LineId = 2, StopId = 4, Order = 4 },
};  

var result =  (from trip in (from l  in lines
              join d in lineStops on l.Id equals d.LineId
              join a in lineStops on l.Id equals a.LineId
              where d.StopId == 2 && a.StopId == 4
              select new { d.LineId })
              join l in lines on trip.LineId equals l.Id
              join ls in lineStops on l.Id equals ls.LineId
              select new { l.Name, ls.StopId, ls.Order }).OrderBy(x => x.Order);

预期结果

Name StopId Order
A-D       1    0
A-D       2    1
A-D       3    3
A-D       4    4