EF6下用C#单Linq查询获取带多对多关联的书籍列表
EF6 单LINQ查询加载书籍及关联BookCategories的最优实现
问题背景
现有如下C#实体类定义(多对多关联的EF6实体):
public class Book { public int BookId { get; set; } public string Title { get; set; } public virtual ICollection<BookCategory> BookCategories { get; set; } } public class Category { public int CategoryId { get; set; } public string CategoryName { get; set; } public virtual ICollection<BookCategory> BookCategories { get; set; } } public class BookCategory { [Key, Column(Order = 1)] public int BookId { get; set; } [Key, Column(Order = 2)] public int CategoryId { get; set; } public Book Book { get; set; } public Category Category { get; set; } }
需要通过单个LINQ查询从数据库获取书籍列表,同时确保每个Book对象的BookCategories属性被完整填充,寻求最优实现方案。
最优实现代码
使用EF6的Include方法显式预加载导航属性,这是EF中解决此类关联加载需求的标准最优方案,能避免N+1查询问题,仅生成一次数据库查询:
using (var context = new YourDbContext()) { // 加载所有书籍及对应的BookCategories关联数据 var booksWithCategories = context.Books .Include(b => b.BookCategories) .ToList(); }
扩展:若需同时加载BookCategories关联的Category实体
如果业务需要同时获取BookCategory对应的Category信息,可以通过ThenInclude(EF6.1及以上版本支持)链式加载:
var booksWithFullCategoryData = context.Books .Include(b => b.BookCategories) .ThenInclude(bc => bc.Category) .ToList();
方案说明
Include方法会让EF生成包含JOIN的SQL查询,一次性从数据库拉取所有书籍及其关联的BookCategories数据,避免了先查书籍再循环查每个书籍的分类关联这种低效的N+1查询模式。- 虽然实体中
BookCategories是virtual属性,EF默认支持延迟加载,但延迟加载会导致多次数据库请求,而显式使用Include的预加载方式是性能最优的选择,尤其在数据量较大的场景下优势明显。
内容的提问来源于stack exchange,提问作者Saurabh Soni
相关产品推荐
相关产品推荐

