Entity Framework Linq to Sql关联查询及子列表数据填充技术问询
嘿,作为Entity Framework新手,碰到这种关联查询+嵌套子列表的需求太常见了,我来给你一步步拆解怎么实现~
首先我先假设你的目标输出类大概是这样的(如果实际结构不同,后面的映射逻辑调整就行):
// 人员输出类,包含关联的公司信息和联系人列表 public class PersonOutput { public string PersonName { get; set; } public int PersonId { get; set; } public string CompanyName { get; set; } public List<ContactOutput> Contacts { get; set; } } // 联系人输出类 public class ContactOutput { public string ContactName { get; set; } public string PhoneNumber { get; set; } }
解决方案:用LINQ+EF填充带关联子列表的输出类
一、EF Core下的实现(推荐)
EF Core支持更清晰的lambda链式关联加载,我们可以用Include预加载关联的公司,Include直接加载联系人子列表,然后通过Select投影到输出类:
using (var context = new YourDbContext()) // 替换成你的DbContext类名 { var personOutputs = context.Persons // 预加载Person关联的Company数据,避免后续懒加载触发额外查询 .Include(p => p.Company) // 预加载Person的Contacts子列表 .Include(p => p.Contacts) // 将数据库实体投影到你的输出类 .Select(person => new PersonOutput { PersonName = person.Name, PersonId = person.Id, CompanyName = person.Company.Name, // 直接访问预加载的Company属性 Contacts = person.Contacts.Select(contact => new ContactOutput { ContactName = contact.Name, PhoneNumber = contact.PhoneNumber }).ToList() // 把联系人列表转成输出类集合 }) .ToList(); }
二、EF6下的兼容写法
如果你用的是旧版EF6,写法类似,关联加载可以用字符串路径或者lambda语法:
using (var context = new YourDbContext()) { var personOutputs = context.Persons // 用字符串路径指定关联,也可以用lambda:.Include(p => p.Company).Include(p => p.Contacts) .Include("Company") .Include("Contacts") .Select(person => new PersonOutput { PersonName = person.Name, PersonId = person.Id, CompanyName = person.Company.Name, Contacts = person.Contacts.Select(contact => new ContactOutput { ContactName = contact.Name, PhoneNumber = contact.PhoneNumber }).ToList() }) .ToList(); }
三、关键注意事项
- 确保关联关系配置正确:你的DbContext里必须正确配置Person与Company、Person与Contact的外键关联(比如用Fluent API或者DataAnnotation特性),不然
Include无法加载关联数据。 - 避免N+1查询问题:一定要用
Include预加载关联数据,不要依赖默认开启的懒加载,否则会在访问关联属性时触发多次数据库查询,严重影响性能。 - 按需投影:只选择输出类需要的字段,不要加载数据库实体的全部属性,这样能让SQL查询更高效。
内容的提问来源于stack exchange,提问作者user3669767
相关产品推荐
相关产品推荐

