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
相关产品推荐
相关产品推荐

