在 Entity Framework Core (EF Core) 中预加载是一种预加载技术与主要实体一起获取相关实体,以避免多次数据库查询。但是,在某些情况下,您在尝试急切加载深层嵌套实体时可能会遇到限制。
考虑以下场景:
public class Order { public int Id { get; set; } public string Name { get; set; } public int CustomerId { get; set; } public Customer Customer { get; set; } } public class Customer { public int Id { get; set; } public string Name { get; set; } public int AddressId { get; set; } public Address Address { get; set; } } public class Address { public int Id { get; set; } public string PostCode { get; set; } public string City { get; set; } }
当您尝试时要使用 Include(nameof(Customer)).ThenInclude(nameof(Address)) 加载订单,您可能会注意到 Customer 实体的 Address 属性为 null。出现这种情况是因为 EF Core 默认不支持急切加载所有嵌套相关实体。
不幸的是,目前官方不支持急切加载 EF Core 中的所有深度嵌套实体。但是,您可以使用两种自定义扩展方法来实现此目的:
包含扩展:
public static IQueryable<T> Include<T>(this IQueryable<T> source, IEnumerable<string> navigationPropertyPaths) where T : class { return navigationPropertyPaths.Aggregate(source, (query, path) => query.Include(path)); }
GetIncludePaths 扩展:
public static IEnumerable<string> GetIncludePaths(this DbContext context, Type clrEntityType, int maxDepth = int.MaxValue) { ... }
在您的通用中存储库中,您可以修改 GetAllAsync 方法,如下所示:
public virtual async Task<IEnumerable<T>> GetAllAsync(Expression<Func<T, bool>> predicate = null) { var query = Context.Set<T>() .Include(Context.GetIncludePaths(typeof(T)); if (predicate != null) query = query.Where(predicate); return await query.ToListAsync(); }
通过使用这些扩展方法,您可以急切加载指定类型的所有嵌套相关实体。
以上是如何在 Entity Framework Core 中预加载深度嵌套实体?的详细内容。更多信息请关注PHP中文网其他相关文章!