EF Core - ThenInclude() on collection with polymorphic elements
EF Core - ThenInclude() on collection with polymorphic elements
我正在尝试从集合的元素中加载属性,该集合本身是另一个 class 的 属性。集合的元素是多态的,不共享我试图包含的属性,并通过 TPH (Table-per-Hierachry) 在数据库中进行跟踪。当我尝试预先加载它们时,会抛出一个异常,指出基础 class 不包含请求的 属性.
我有一个抽象基础 class Base
和两个派生 classes DerivedA
和 DerivedB
。 Base
已经为 TPH 配置了这样的
internal static void Configure(ModelBuilder builder)
{
// Get the EntityTypeBuilder from the given ModelBuilder
EntityTypeBuilder<Base> entityBuilder = builder.Entity<Base>();
// Configure TPH
entityBuilder.ToTable("Bases").HasDiscriminator<int>("DerivedType")
.HasValue<DerivedA>(0)
.HasValue<DerivedB>(1);
}
此外,我有一个 class ToBeLoaded
和一个 属性 public ICollection<Base> Bases {get; set; }
,其中包含 DerivedA
和 DerivedB
。我期待 EF Core 能够处理这个问题。我错了吗?
EF Core Docs 说我可以在 ThenInclude()
中使用 as
或直接转换,就像我在扩展方法中所做的那样。
public static IQueryable<ToBeLoaded> LoadRelated(this DbSet<ToBeLoaded> toBeLoadedSet)
{
return toBeLoadedSet.Include(tbl => tbl.Bases)
.ThenInclude(b => (b as DerivedA).PropA)
.Include(tbl => tbl.Bases)
.ThenInclude(b => (b as DerviedB).PropB);
}
然后调用 context.ToBeLoadedSet.LoadRelated.ToList();
时抛出以下异常
System.InvalidOperationException: 'The property 'PropA' is not a navigation property of entity type 'Base'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.'
我已经尝试使用文档中建议的其他方法来实现这一点,即直接转换和 Include(string)
方法。
我知道这与文档中的示例有些不同,但这是我能找到的最接近我的情况的东西。
这在理论上是否可以使用 Include 界面,或者我应该尝试使用 RawSQL?
所以在写完整个问题后,我又尝试了一件事情。仅包括 Bases
,如 toBeLoadedSet.Include(tbl => tbl.Bases)
。出于某种原因,我认为我之前尝试过这个,然后 PropA
和 ProbB
其中 null
,但只是想确定一下。
既然它现在已经存在了,它可能会阻止其他人浪费他们的时间,所以我就 post 它。谢谢你做我的橡皮鸭。
明确地说,LoadRelated
方法现在看起来像这样
public static IQueryable<ToBeLoaded> LoadRelated(this DbSet<ToBeLoaded> toBeLoadedSet)
{
return toBeLoadedSet.Include(tbl => tbl.Bases);
}
我正在尝试从集合的元素中加载属性,该集合本身是另一个 class 的 属性。集合的元素是多态的,不共享我试图包含的属性,并通过 TPH (Table-per-Hierachry) 在数据库中进行跟踪。当我尝试预先加载它们时,会抛出一个异常,指出基础 class 不包含请求的 属性.
我有一个抽象基础 class Base
和两个派生 classes DerivedA
和 DerivedB
。 Base
已经为 TPH 配置了这样的
internal static void Configure(ModelBuilder builder)
{
// Get the EntityTypeBuilder from the given ModelBuilder
EntityTypeBuilder<Base> entityBuilder = builder.Entity<Base>();
// Configure TPH
entityBuilder.ToTable("Bases").HasDiscriminator<int>("DerivedType")
.HasValue<DerivedA>(0)
.HasValue<DerivedB>(1);
}
此外,我有一个 class ToBeLoaded
和一个 属性 public ICollection<Base> Bases {get; set; }
,其中包含 DerivedA
和 DerivedB
。我期待 EF Core 能够处理这个问题。我错了吗?
EF Core Docs 说我可以在 ThenInclude()
中使用 as
或直接转换,就像我在扩展方法中所做的那样。
public static IQueryable<ToBeLoaded> LoadRelated(this DbSet<ToBeLoaded> toBeLoadedSet)
{
return toBeLoadedSet.Include(tbl => tbl.Bases)
.ThenInclude(b => (b as DerivedA).PropA)
.Include(tbl => tbl.Bases)
.ThenInclude(b => (b as DerviedB).PropB);
}
然后调用 context.ToBeLoadedSet.LoadRelated.ToList();
时抛出以下异常
System.InvalidOperationException: 'The property 'PropA' is not a navigation property of entity type 'Base'. The 'Include(string)' method can only be used with a '.' separated list of navigation property names.'
我已经尝试使用文档中建议的其他方法来实现这一点,即直接转换和 Include(string)
方法。
我知道这与文档中的示例有些不同,但这是我能找到的最接近我的情况的东西。
这在理论上是否可以使用 Include 界面,或者我应该尝试使用 RawSQL?
所以在写完整个问题后,我又尝试了一件事情。仅包括 Bases
,如 toBeLoadedSet.Include(tbl => tbl.Bases)
。出于某种原因,我认为我之前尝试过这个,然后 PropA
和 ProbB
其中 null
,但只是想确定一下。
既然它现在已经存在了,它可能会阻止其他人浪费他们的时间,所以我就 post 它。谢谢你做我的橡皮鸭。
明确地说,LoadRelated
方法现在看起来像这样
public static IQueryable<ToBeLoaded> LoadRelated(this DbSet<ToBeLoaded> toBeLoadedSet)
{
return toBeLoadedSet.Include(tbl => tbl.Bases);
}