entity frameworkCore 2.0.1 Eager加载所有嵌套的相关实体

我有一个简单的问题,但似乎无法找到解决方法。 我正在使用Entity Framework Core版本2.0.1,并希望默认加载我的所有实体。

例:

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; } } 

但是当我加载Order实体时,相关实体Customer然后在其内部Address为null

我尝试过的:

  • 尝试升级到版本2.1并使用LazyLoadingProxies设置为false

这只是一个例子,我有多个嵌套级别的实体,我想在Generic Repository中加载嵌套的相关数据,所以不能使用IncludeThenInclude,因为我不知道加载它时的实际实体类型。

例:

  public virtual async Task<IEnumerable> GetAllAsync(Expression<Func> predicate = null) { if (predicate == null) { return await Context.Set().ToListAsync(); } return await Context.Set().Where(predicate).ToListAsync(); } 

我错过了什么? 我在存储库中有什么问题吗? 任何有关更好设计的帮助或指针(如果这就是问题在这里)都会受到赞赏。

谢谢

目前官方不存在此类function(EF Core 2.0.2以及传入的2.1)。 已在Eager中请求加载所有导航属性#4851 (已关闭),并且当前由基于规则的 预先加载 (包括)#2953跟踪并允许在模型中声明聚合(例如,定义包含的属性或通过其他方式)#1985 (都在Backlog中,即没有具体的时间表)。

我可以提供以下两种自定义扩展方法:

 using System; using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore.Metadata; namespace Microsoft.EntityFrameworkCore { public static partial class CustomExtensions { public static IQueryable Include(this IQueryable source, IEnumerable navigationPropertyPaths) where T : class { return navigationPropertyPaths.Aggregate(source, (query, path) => query.Include(path)); } public static IEnumerable GetIncludePaths(this DbContext context, Type clrEntityType) { var entityType = context.Model.FindEntityType(clrEntityType); var includedNavigations = new HashSet(); var stack = new Stack>(); while (true) { var entityNavigations = new List(); 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的便捷方式。

第二个是使用EF Core提供的元数据收集类型的所有Include路径的实际工作。 它基本上是指向循环图处理,从传递的实体类型开始,不包括所包含路径的反向导航,只发送到“叶子”节点的路径。

您的示例中的用法可能如下所示:

 public virtual async Task> GetAllAsync(Expression> predicate = null) { var query = Context.Set() .Include(Context.GetIncludePaths(typeof(T)); if (predicate != null) query = query.Where(predicate); return await query.ToListAsync(); }