匹配条件下将B列表项关联到A类listB的代码问题求助
问题:将匹配的B对象关联到对应A的listB集合中
类定义
class A{ int id; string name; string type; List<B> listB; } class B{ int id; int refid; string value; }
示例数据
var ListofA = new List<A>() { new A {id=1,name="ABC",type="A",listB=null}, new A {id=1,name="ABC",type="A",listB=null} }; var ListofB = new List<B>() { new B {id=4,refid=1,value="ABC"}, new B {id=5,refid=1,value="DEF"}, new B {id=6,refid=2,value="XYZ"} };
需求与问题
需求:将满足A.id == B.refid条件的B对象添加到对应的A的listB集合中。
我尝试了以下代码,但得到的listB都是空列表:
ListofA = ListofA.Select(a => new A { id = a.id, name =a.name, type = a.type, listB = ListofB.Where(b => b.refid == a.id).ToList() }).ToList();
请问我哪里遗漏了?恳请帮助,谢谢!
问题排查与修正
嘿,我发现问题啦!你写的逻辑本身是对的,但大概率是因为类的成员访问权限问题——你的A和B类里的字段都是默认的私有(private)访问级别,在外部代码里根本没办法直接访问这些字段!
在C#中,类的成员默认是private的,这意味着你在Select里给新A对象赋值id = a.id的时候,其实根本拿不到原A对象的id值,同理B类的refid也拿不到,导致Where条件永远不成立,所以listB是空的。
修正步骤:
- 把类的字段改成**公共(public)**访问级别,或者给它们加上公共的属性(Property):
方案1:直接把字段设为public
public class A{ public int id; public string name; public string type; public List<B> listB; } public class B{ public int id; public int refid; public string value; }
方案2:使用C#自动属性(更推荐的规范写法)
public class A{ public int Id { get; set; } public string Name { get; set; } public string Type { get; set; } public List<B> ListB { get; set; } } public class B{ public int Id { get; set; } public int RefId { get; set; } public string Value { get; set; } }
- 如果用了自动属性,记得修改查询代码对应使用属性名:
ListofA = ListofA.Select(a => new A { Id = a.Id, Name = a.Name, Type = a.Type, ListB = ListofB.Where(b => b.RefId == a.Id).ToList() }).ToList();
额外优化建议
如果你的ListofA和ListofB数据量较大,直接用Where遍历效率会偏低,建议先把ListofB按refid分组,提升匹配效率:
// 先按refid分组,把相同refid的B对象归类 var bGrouped = ListofB.GroupBy(b => b.RefId).ToDictionary(g => g.Key, g => g.ToList()); ListofA = ListofA.Select(a => new A { Id = a.Id, Name = a.Name, Type = a.Type, // 存在对应分组就取集合,不存在返回空列表 ListB = bGrouped.TryGetValue(a.Id, out var bs) ? bs : new List<B>() }).ToList();
这样修改后,你的代码就能正常关联A和B对象啦!
内容的提问来源于stack exchange,提问作者Girish Mahida
相关产品推荐
相关产品推荐

