C#中使用SelectMany展平时子列表为空如何保留父列表数据
解决嵌套列表为空时SelectMany无结果的问题
首先修正类定义中的不一致问题:你的InventoryModel里的products是List<Product>,但实际定义的类是ProductModel,需要统一名称,比如修改InventoryModel的定义:
public class InventoryModel { public string inventoryCode {get;set;} public string inventoryDescription {get;set;} public List<ProductModel> products {get;set;} // 改为List<ProductModel> }
原代码的问题是:当products或shares为空时,SelectMany会返回空序列,导致对应的父级数据被完全过滤。要保留父级数据,需要用DefaultIfEmpty()为空子列表提供默认实例,确保每个父级条目至少生成一条结果。
修改后的代码如下:
var invenFlatList = lstInventory .SelectMany(x => // 处理空products列表,提供默认ProductModel实例 x.products?.DefaultIfEmpty(new ProductModel()) ?? new List<ProductModel> { new ProductModel() } .SelectMany(y => // 处理空shares列表,提供默认Share实例 y.share?.DefaultIfEmpty(new Share()) ?? new List<Share> { new Share() } .Select(z => new NewModel { inventoryCode = x.inventoryCode, inventoryDescription = x.inventoryDescription, productCode = y.productCode, // 空子列表时为null productName = y.productName, // 空子列表时为null shareCode = z.shareCode, // 空子列表时为null shareNumber = z.shareNumber // 空子列表时为0(int类型默认值) }) ) ) .ToList();
代码说明
x.products?.DefaultIfEmpty(new ProductModel()) ?? new List<ProductModel> { new ProductModel() }:先判断products是否为null,若为null则直接生成包含默认实例的列表;若不为null但为空,用DefaultIfEmpty添加一个默认ProductModel,确保父级条目不会被过滤。y.share?.DefaultIfEmpty(new Share()) ?? new List<Share> { new Share() }:同理处理shares列表为空或null的情况。- 最终生成的
NewModel中,空子列表对应的属性会是类型的默认值(字符串为null,int为0),但父级的inventoryCode和inventoryDescription始终会保留。
如果希望空子列表时product或share的属性更明确(比如productCode设为""而不是null),可以修改默认实例的初始化值,例如:
new ProductModel { productCode = "", productName = "", share = new List<Share>() }
内容的提问来源于stack exchange,提问作者Vishal Dhasal
相关产品推荐
相关产品推荐

