我在一个表中有这些数据,我正在尝试执行循环或递归方法。我需要根据会议 ID 获取结果。如果我使用会议 ID 1,它将返回 2,3。如果我使用会议 ID 2,我将得到 1,3,如果我使用 3,我将得到 1,2。我有这个方法,但我需要多次调用,我想知道是否有更好的方法。我相信我需要 linq 来遍历父/先前会议链和遍历子/延续会议链。
MeetingId ContinuedMeetingId
---------- -------------
1 2
2 3
3 null
EF / Linq:
var y = (from m in Meetings
where m.MeetingId == MeetingId
select new
{
ContinuedMeetingsId = db.Meetings
.Where(s => s.MeetingId == m.MeetingId)
.Select(s => s.ContinuedMeetingId).FirstOrDefault()
}).FirstOrDefault();
这可以在 SQL 中使用两个递归 CTE 来实现 - 一个遍历父/先前会议链,另一个遍历子/延续会议链。(原始会议被排除在两个列表之外。)然后只需执行 and
UNION ALL
(如果需要)即可STRING_AGG()
构建最终的逗号分隔列表。该逻辑可以包含在用户定义的函数中,然后可以将其添加到实体框架模型中并从应用程序中调用。
上述逻辑假设会议链是线性的,具有 1 对 1 的父/子关系。如果会议关系可以是多对多,则图的遍历将更加复杂。
虽然可以在 C# 中实现类似的逻辑,但我不知道如何编写等效的递归 LINQ 语句来映射到单个 SQL 查询执行。本机 LINQ 实现可能会循环并执行多个查询。(我相信有一些附加组件提供有限的 CTE 支持,但我不知道它们是否支持递归或是否适用于此解决方案。这需要进一步调查。)
结果(附带一些额外的测试数据):
请参阅此 db<>fiddle了解演示。
老实说,我仍然不确定你想做什么。你只是通过从收到的第一个答案中复制和粘贴一些关键字来编辑你的问题。
因此我只是假设前面的答案或多或少符合你所寻找的内容。
您还
var y = (from m in Meetings where m.MeetingId == MeetingId select new{}).FirstOrDefault()
可以通过使用来简化Meetings.FirstOrDefault(m => m.MeetingId == MeetingId)
。要在 Csharp 中编写 while 循环或递归方法,您可以尝试以下代码:
草稿,社区答案
以下是使用LINQ To DB - 通用表表达式 (CTE)功能的早期 SQL 递归 CTE 答案的可能的 LINQ 实现。
这篇初始帖子是根据文档将 SQL 翻译为 C# LINQ 的草稿,但尚未经过测试,可能需要更正。我没有这方面的经验,所以可能需要修复或其他改进。请随意编辑和改进此答案。如果您可以验证这是一个可行的解决方案,这些评论可能会被适当地编辑或删除。