You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用LINQ在SQL Server中连接三个表并生成单行结果?

使用LINQ实现三表关联并合并单行输出的解决方案

嘿,我帮你梳理了用LINQ实现People、Appointment、Participant三表关联,并且把关联的参与者信息合并成单行的方案,先明确下咱们的表结构和期望结果:

数据表结构

People表

IdNameSurname
1DavidDavid1
2AmeyyAmeyy2

Appointment表

IdPeopleIdSubject
191description

Participant表

IdAppointmentIdPeopleId
1191
2192

期望的Result表

IdSubjectParticipant
19descriptionDavid David1, Ameyy Ameyy2

LINQ实现方案

下面分两种场景给你实现代码,你可以根据自己的实际情况选用:

1. 内存集合的LINQ查询(比如处理本地数据)

首先咱们先定义对应的实体类,模拟数据后再做查询:

// 实体类定义
public class People
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Surname { get; set; }
}

public class Appointment
{
    public int Id { get; set; }
    public int PeopleId { get; set; }
    public string Subject { get; set; }
}

public class Participant
{
    public int Id { get; set; }
    public int AppointmentId { get; set; }
    public int PeopleId { get; set; }
}

// 模拟测试数据
var peopleList = new List<People>
{
    new People { Id = 1, Name = "David", Surname = "David1" },
    new People { Id = 2, Name = "Ameyy", Surname = "Ameyy2" }
};

var appointmentList = new List<Appointment>
{
    new Appointment { Id = 19, PeopleId = 1, Subject = "description" }
};

var participantList = new List<Participant>
{
    new Participant { Id = 1, AppointmentId = 19, PeopleId = 1 },
    new Participant { Id = 2, AppointmentId = 19, PeopleId = 2 }
};

// 核心关联查询+合并逻辑
var result = from appt in appointmentList
             join part in participantList on appt.Id equals part.AppointmentId
             join person in peopleList on part.PeopleId equals person.Id
             // 按预约的Id和主题分组,保证每个预约一行
             group new { person } by new { appt.Id, appt.Subject } into groupedData
             select new
             {
                 Id = groupedData.Key.Id,
                 Subject = groupedData.Key.Subject,
                 // 把分组里的参与者姓名用逗号拼接成字符串
                 Participant = string.Join(", ", groupedData.Select(p => $"{p.person.Name} {p.person.Surname}"))
             };

// 输出结果看看
foreach (var item in result)
{
    Console.WriteLine($"Id: {item.Id}, Subject: {item.Subject}, Participant: {item.Participant}");
}

2. EF Core中的LINQ查询(直接操作数据库)

如果是用EF Core操作数据库,为了避免把所有数据拉到内存处理,推荐用EF Core 6+版本的特性,它会把string.Join翻译成数据库原生的聚合函数(比如SQL Server的STRING_AGG),性能更优:

// 假设你已经有DbContext,包含三个表的DbSet
var result = await _context.Appointments
    // 关联预约和参与者表
    .Join(_context.Participants, 
          appt => appt.Id, 
          part => part.AppointmentId, 
          (appt, part) => new { Appointment = appt, Participant = part })
    // 再关联参与者对应的人员表
    .Join(_context.People, 
          combined => combined.Participant.PeopleId, 
          person => person.Id, 
          (combined, person) => new { combined.Appointment, Person = person })
    // 按预约的Id和主题分组
    .GroupBy(data => new { data.Appointment.Id, data.Appointment.Subject })
    // 拼接参与者信息
    .Select(grouped => new
    {
        Id = grouped.Key.Id,
        Subject = grouped.Key.Subject,
        Participant = string.Join(", ", grouped.Select(d => $"{d.Person.Name} {d.Person.Surname}"))
    })
    .ToListAsync();

关键点说明

  • 核心逻辑是先完成三表关联,再按预约的唯一标识(Id+Subject)分组,最后在分组内把每个参与者的姓名合并成单个字符串。
  • 内存场景用string.Join直接处理分组后的集合;数据库场景下EF Core会自动帮我们把拼接逻辑转换成数据库能执行的SQL,不用自己写原生SQL。

内容的提问来源于stack exchange,提问作者yuksel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:20:54