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

C#中如何将父对象列表里的子对象属性展开至父级列表

C#中如何将父对象列表里的子对象属性展开至父级列表

嘿,我完全懂你现在的需求——你不想让Enrolements列表里的user对象以嵌套的形式存在,而是希望把EnrolmentUsers里的那些属性(比如用户ID、姓名、邮箱这些)直接和Enrolements自身的属性合并到同一个层级,让整个列表的每一项都包含所有你需要的信息,对吧?

你之前尝试的Select(parent => parent.user)其实只是把所有子对象单独提取出来组成了一个新列表,这当然不是你想要的效果。咱们可以通过两种方式来实现属性“平铺”的需求:

方法一:创建一个合并属性的DTO类(推荐用于需要复用的场景)

如果这个展开后的结构需要在多个地方使用,最好定义一个专门的数据传输对象(DTO),把所有需要的属性都放在这个类里:

// 定义包含所有合并属性的DTO类
public class EnrollmentWithUserDetails
{
    // 原Enrolements的属性
    public int enrollment_id { get; set; }
    public string content_type { get; set; }
    public string module_name { get; set; }
    public string campaign_name { get; set; }
    public string enrollment_date { get; set; }
    public string start_date { get; set; }
    public string completion_date { get; set; }
    public string status { get; set; }
    public int time_spent { get; set; }
    public bool policy_acknowledged { get; set; }

    // 来自EnrolmentUsers的属性(可以加前缀区分)
    public int user_id { get; set; }
    public string user_first_name { get; set; }
    public string user_last_name { get; set; }
    public string user_email { get; set; }
    public string user_employee_number { get; set; }
}

接着用LINQ把原列表转换为这个新类的列表:

var flattenedEnrollments = enrolementList.Select(enrollment => new EnrollmentWithUserDetails
{
    // 赋值原Enrolements的属性
    enrollment_id = enrollment.enrollment_id,
    content_type = enrollment.content_type,
    module_name = enrollment.module_name,
    campaign_name = enrollment.campaign_name,
    enrollment_date = enrollment.enrollment_date,
    start_date = enrollment.start_date,
    completion_date = enrollment.completion_date,
    status = enrollment.status,
    time_spent = enrollment.time_spent,
    policy_acknowledged = enrollment.policy_acknowledged,

    // 赋值User子对象的属性
    user_id = enrollment.user.id,
    user_first_name = enrollment.user.first_name,
    user_last_name = enrollment.user.last_name,
    user_email = enrollment.user.email,
    user_employee_number = enrollment.user.employee_number
}).ToList();

这样flattenedEnrollments里的每一项就都包含了父级和子级的所有属性,没有嵌套结构了。

方法二:使用匿名类型(适合临时使用的场景)

如果这个展开后的结构只是临时用一下,不需要复用,那可以直接用匿名类型,省去创建新类的步骤:

var flattenedEnrollments = enrolementList.Select(enrollment => new
{
    // 直接引用原Enrolements的属性
    enrollment.enrollment_id,
    enrollment.content_type,
    enrollment.module_name,
    enrollment.campaign_name,
    enrollment.enrollment_date,
    enrollment.start_date,
    enrollment.completion_date,
    enrollment.status,
    enrollment.time_spent,
    enrollment.policy_acknowledged,

    // 给User的属性命名,方便区分
    UserId = enrollment.user.id,
    UserFirstName = enrollment.user.first_name,
    UserLastName = enrollment.user.last_name,
    UserEmail = enrollment.user.email,
    UserEmployeeNumber = enrollment.user.employee_number
}).ToList();

注意事项

如果enrollment.user有可能为null,记得加上空值判断,避免空引用异常,比如用C# 6及以上支持的空条件运算符:

UserId = enrollment.user?.id ?? 0, // 如果user为null,给默认值0
UserFirstName = enrollment.user?.first_name ?? string.Empty

这样处理后,你就能得到一个所有属性都在同一层级的列表啦!

备注:内容来源于stack exchange,提问作者user16592152

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 11:38:08