Entity Framework Core 2.0.1默认预加载所有嵌套关联实体的实现咨询
嘿,这个问题我之前也踩过坑!EF Core 2.0.1本身没有直接全局开启所有嵌套关联预加载的配置,不过有几个实用的方案可以帮你实现需求,下面给你详细拆解:
方案1:自定义扩展方法封装全局Include逻辑
这是最适配你当前版本的解决方案,我们可以写一个通用的扩展方法,把所有需要预加载的嵌套关联都通过Include和ThenInclude串联起来,后续查询时直接调用即可。
针对你的Order、Customer、Address模型,示例代码如下:
using Microsoft.EntityFrameworkCore; public static class QueryableExtensions { public static IQueryable<TEntity> IncludeAllNested<TEntity>(this IQueryable<TEntity> query) where TEntity : class { var entityType = typeof(TEntity); // 处理Order的嵌套关联 if (entityType == typeof(Order)) { return query .Include(o => o.Customer) .ThenInclude(c => c.Address) as IQueryable<TEntity>; } // 如果还有其他实体需要全局预加载,在这里继续添加判断 // 比如处理Customer的关联: // if (entityType == typeof(Customer)) // { // return query.Include(c => c.Address) as IQueryable<TEntity>; // } return query; } }
使用的时候就非常简洁了:
var orders = dbContext.Orders.IncludeAllNested().ToList();
这个方案的唯一缺点是如果后续实体的关联关系变更,你需要同步更新这个扩展方法,但胜在可控性强,完全适配EF Core 2.0.1。
方案2:开启懒加载(替代预加载的折中方案)
如果你的核心需求是避免手动写Include,同时不介意“用到才加载”的逻辑,那懒加载也是一个可行的选择。EF Core 2.0.1开启懒加载需要以下几步:
- 安装
Microsoft.EntityFrameworkCore.ProxiesNuGet包 - 在DbContext的
OnConfiguring方法中启用懒加载代理:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .UseLazyLoadingProxies() .UseSqlServer("你的数据库连接字符串"); }
- 将所有导航属性标记为
virtual:
public class Order { public int Id { get; set; } public string Name { get; set; } public int CustomerId { get; set; } public virtual Customer Customer { get; set; } } public class Customer { public int Id { get; set; } public string Name { get; set; } public int AddressId { get; set; } public virtual Address Address { get; set; } }
这样当你访问order.Customer或者customer.Address时,EF会自动触发关联数据的加载。不过要注意,这是懒加载,不是预加载,可能会产生N+1查询问题,适合数据量较小的场景。
方案3:后续版本的便捷方案(仅供参考)
注意:这个方案不适用于EF Core 2.0.1,只是给你提个醒
从EF Core 5.0开始,官方提供了AutoInclude API,可以直接在模型配置中指定某个导航属性默认自动加载:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Order>() .Navigation(o => o.Customer) .AutoInclude(); modelBuilder.Entity<Customer>() .Navigation(c => c.Address) .AutoInclude(); }
这样每次查询Order时,会自动预加载Customer,查询Customer时自动预加载Address,但2.0.1版本还没有这个特性,如果你有升级版本的计划,可以考虑这个方案。
内容的提问来源于stack exchange,提问作者Jinish
相关产品推荐
相关产品推荐

