如何在LINQ中为父列表添加多条子记录
问题描述
我的类定义如下:
public class ParentModel { public int ID { get; set; } public string ParentName { get; set; } public List<ChildModel> ChildModel { get; set; } } public class ChildModel { public int ParentID { get; set; } public string ChildName { get; set; } }
我目前的使用代码如下:
List<ParentModel> parentModel = new List<ParentModel>(); using(MyEntities db = new MyEntities()) { foreach(Parent parent in db.Parents.Where(some_condition_here)) { parentModel.Add ( new ParentModel { ID = parent.ID, ParentName = parent.ParentName } ); } }
问题在于我不知道如何为每个父记录添加对应的子记录,无法构建正确的语法。请问如何为每个父记录包含对应的子记录?
解决方案
方法1:预加载+投影(推荐,避免N+1查询)
利用EF的Include方法一次性加载父实体和关联的子实体,再通过投影直接构建目标模型,性能最优:
List<ParentModel> parentModel; using(MyEntities db = new MyEntities()) { parentModel = db.Parents .Where(some_condition_here) .Include(p => p.Children) // 假设EF中Parent实体的子集合导航属性名为Children .Select(p => new ParentModel { ID = p.ID, ParentName = p.ParentName, ChildModel = p.Children.Select(c => new ChildModel { ParentID = c.ParentID, ChildName = c.ChildName }).ToList() }) .ToList(); }
方法2:循环内查询子记录(简单但性能较差)
如果不想配置导航属性,可以在遍历父实体时,单独查询对应父ID的子记录:
List<ParentModel> parentModel = new List<ParentModel>(); using(MyEntities db = new MyEntities()) { foreach(Parent parent in db.Parents.Where(some_condition_here)) { // 查询当前父记录对应的所有子记录 var childEntities = db.Children.Where(c => c.ParentID == parent.ID).ToList(); parentModel.Add(new ParentModel { ID = parent.ID, ParentName = parent.ParentName, ChildModel = childEntities.Select(c => new ChildModel { ParentID = c.ParentID, ChildName = c.ChildName }).ToList() }); } }
方法3:直接投影子集合(无需导航属性)
不依赖实体导航属性,直接在投影中关联子表查询:
List<ParentModel> parentModel; using(MyEntities db = new MyEntities()) { parentModel = db.Parents .Where(some_condition_here) .Select(p => new ParentModel { ID = p.ID, ParentName = p.ParentName, ChildModel = db.Children .Where(c => c.ParentID == p.ID) .Select(c => new ChildModel { ParentID = c.ParentID, ChildName = c.ChildName }).ToList() }) .ToList(); }
注意事项
- 确保数据库中
Parent和Child表已建立正确的外键关联,这样EF才能正确识别导航属性。 - 优先选择方法1或方法3,避免方法2的N+1查询问题(每遍历一个父实体就发起一次子查询,数据量大时性能损耗明显)。
内容的提问来源于stack exchange,提问作者Frank Martin
相关产品推荐
相关产品推荐

