该功能目前正式不存在(EF Core 2.0.2以及即将推出的2.1)。已在“
急切加载”中请求所有导航属性#4851(已关闭),目前已通过基于规则的急切加载(包括)#2953和允许在模型中声明聚合(例如,定义包含的属性或通过其他方式)进行跟踪#1985(均在积压中,即没有具体的时间表)。
我可以提供以下两种自定义扩展方法:
using System;using System.Collections.Generic;using System.Linq;using Microsoft.EntityframeworkCore.metadata;namespace Microsoft.EntityframeworkCore{ public static partial class CustomExtensions { 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)); } public static IEnumerable<string> GetIncludePaths(this DbContext context, Type clrEntityType) { var entityType = context.Model.FindEntityType(clrEntityType); var includedNavigations = new HashSet<INavigation>(); var stack = new Stack<IEnumerator<INavigation>>(); while (true) { var entityNavigations = new List<INavigation>(); foreach (var navigation in entityType.GetNavigations()) { if (includedNavigations.Add(navigation)) entityNavigations.Add(navigation); } if (entityNavigations.Count == 0) { if (stack.Count > 0) yield return string.Join(".", stack.Reverse().Select(e => e.Current.Name)); } else { foreach (var navigation in entityNavigations) { var inverseNavigation = navigation.FindInverse(); if (inverseNavigation != null) includedNavigations.Add(inverseNavigation); } stack.Push(entityNavigations.GetEnumerator()); } while (stack.Count > 0 && !stack.Peek().MoveNext()) stack.Pop(); if (stack.Count == 0) break; entityType = stack.Peek().Current.GetTargetType(); } } }}第一种只是应用多个字符串库的便捷方法
Include。
第二个步骤
Include使用EF
Core提供的元数据来完成收集类型的所有路径的实际工作。它基本上是从所传递的实体类型开始的有向循环图处理,不包括所包含路径的逆向导航,仅发送到“叶”节点的路径。
您的示例中的用法可能是这样的:
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();}


