【问题标题】:How to use result of first join in second join in LINQ to SQL如何在 LINQ to SQL 的第二次连接中使用第一次连接的结果
【发布时间】:2019-11-28 11:43:52
【问题描述】:

我有 2 条记录的列表。列表 A 和列表 B。列表 A 在任务表中有 4 个任务,列表 B 在任务表中有 2 个任务。列表 A 的任务 1 在 TimeLog 表中有两个时间日志条目。未使用外键。

现在考虑下面的代码。

var objs = from project_task_list in modelRepository.Get()
                       join project_task in projectTaskRepository.Get() on project_task_list.ListId equals project_task.ListId into project_task_result
                       join project_task_timelog in projectTaskTimeLogRepository.Get() on project_task.TaskId equals project_task_timelog.TaskId into project_task_timelog_result
                       where project_task_list.ProjectId == project_id
                       select new ProjectTaskListModel
                       {
                           ListId = project_task_list.ListId,
                           ProjectId = project_task_list.ProjectId ?? 0,
                           ListName = project_task_list.ListName,
                           ListStartDate = project_task_list.ListStartDate,
                           ListEndDate = project_task_list.ListEndDate,
                           ListStatusId = project_task_list.ListStatusId ?? 0,
                           ListSortOrder = project_task_list.ListSortOrder ?? 0,

                           ListTasksEstimatedHours = project_task_result.Sum(x => x.TaskEstimatedHours) ?? 0,
                           ListTasksTimeLogTotalMinutes = project_task_timelog_result.Sum(x => x.LogMinutes) ?? 0
                       };

我想在另一个连接中使用一个连接的结果,但我遇到了以下语法错误。

我也试过下面的代码。

var objs = from project_task_list in modelRepository.Get()
                       join project_task in projectTaskRepository.Get() on project_task_list.ListId equals project_task.ListId into project_task_result
                       from project_task in project_task_result.DefaultIfEmpty()
                       join project_task_timelog in projectTaskTimeLogRepository.Get() on project_task.TaskId equals project_task_timelog.TaskId into project_task_timelog_result
                       where project_task_list.ProjectId == project_id
                       select new ProjectTaskListModel
                       {
                           ListId = project_task_list.ListId,
                           ProjectId = project_task_list.ProjectId ?? 0,
                           ListName = project_task_list.ListName,
                           ListStartDate = project_task_list.ListStartDate,
                           ListEndDate = project_task_list.ListEndDate,
                           ListStatusId = project_task_list.ListStatusId ?? 0,
                           ListSortOrder = project_task_list.ListSortOrder ?? 0,

                           ListTasksEstimatedHours = project_task_result.Sum(x => x.TaskEstimatedHours) ?? 0,
                           ListTasksTimeLogTotalMinutes = project_task_timelog_result.Sum(x => x.LogMinutes) ?? 0
                       };

语法错误消失了,但问题是它返回 6 条记录,而我在列表中只有 2 条记录。我究竟做错了什么?提前致谢。

【问题讨论】:

  • 每个帖子一个问题。但是请注意,性能问题往往无法回答。更不用说我们对数据和架构一无所知了。
  • @GertArnold 这不是性能问题,也不是两个问题。这是一个简单的问题,我无法从我发布的 LINQ 查询中获得期望的结果。我已经证明了我已经尝试过的。我会尝试发布一些示例数据,但我认为这不会有太大帮助。
  • 执行into 后,join 的范围变量不再在范围内 - 它已被into 吸收。
  • 感谢@NetMage。是的,我明白这一点,如果您查看我发布的最后一个代码块,我使用了来自连接结果的 from 子句,语法错误消失了,但现在结果包含来自列表和任务表的行,这就是我无法修复。
  • 第二个from 本质上为每个匹配的任务行创建一个结果条目,如果您不希望您需要更改joins 的优先级。您只想要列表 A 的 Task1 还是想要没有时间条目的任务?

标签: c# sql linq linq-to-sql


【解决方案1】:

我自己已经弄清楚了。我只需要 LINQ 中的 GROUP BY 子句。这是最终的查询。

var objs = from project_task_list in modelRepository.Get()
                       join project_task in projectTaskRepository.Get() on project_task_list.ListId equals project_task.ListId into project_task_result
                       from project_task in project_task_result.DefaultIfEmpty()
                       join project_task_timelog in projectTaskTimeLogRepository.Get() on project_task.TaskId equals project_task_timelog.TaskId into project_task_timelog_result
                       from project_task_timelog in project_task_timelog_result.DefaultIfEmpty()
                       where project_task_list.ProjectId == project_id

                       group new { project_task_list, project_task, project_task_timelog } by new
                       {
                           project_task_list.ListId,
                           project_task_list.ProjectId,
                           project_task_list.ListName,
                           project_task_list.ListStartDate,
                           project_task_list.ListEndDate,
                           project_task_list.ListStatusId,
                           project_task_list.ListSortOrder
                       } into group_result

                       select new ProjectTaskListModel
                       {
                           ListId = group_result.Key.ListId,
                           ProjectId = group_result.Key.ProjectId ?? 0,
                           ListName = group_result.Key.ListName,
                           ListStartDate = group_result.Key.ListStartDate,
                           ListEndDate = group_result.Key.ListEndDate,
                           ListStatusId = group_result.Key.ListStatusId ?? 0,
                           ListSortOrder = group_result.Key.ListSortOrder ?? 0,

                           ListTasksEstimatedHours = group_result.Sum(x => x.project_task.TaskEstimatedHours) ?? 0,
                           ListTasksTimeLogTotalMinutes = group_result.Sum(x => x.project_task_timelog.LogMinutes) ?? 0
                       };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2023-01-18
    • 1970-01-01
    相关资源
    最近更新 更多