EF Core - ThenInclude () для коллекции с полиморфными элементами - PullRequest
0 голосов
/ 25 сентября 2019

Я пытаюсь загрузить свойства из элементов коллекции, которая сама является свойством другого класса.Элементы коллекции полиморфны, не разделяют свойства, которые я пытаюсь включить, и отслеживаются в БД через TPH (Table-per-Hierachry).Когда я пытаюсь загрузить их, выдается исключение, заявляющее, что базовый класс не содержит запрошенное свойство.

У меня есть абстрактный базовый класс Base и два производных класса 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);
}

Более того, у меня есть класс ToBeLoaded со свойством public ICollection<Base> Bases {get; set; }, которое содержит как DerivedA, так и DerivedB.Я ожидаю, что EF Core сможет справиться с этим.Неужели я не прав?

В базовых документах EF говорится, что я могу использовать as или прямое приведение в пределах ThenInclude(), как в моем методе расширения.

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).Я знаю, что это несколько отличается от примера в документации, но это самая близкая вещь к моей ситуации, которую я смог найти.

Возможно ли это даже теоретически с помощью интерфейса Включить, или я должен просто попытаться использовать RawSQL

1 Ответ

0 голосов
/ 25 сентября 2019

Так что после написания всего вопроса я попробовал еще одну вещь.Просто включая Bases как toBeLoadedSet.Include(tbl => tbl.Bases).По какой-то причине я подумал, что пытался сделать это раньше, а затем PropA и ProbB, где null, но просто хотел быть уверен.

Так как он сейчас есть, и это может помешать кому-то другому тратить ихраз, я просто опубликую это.Спасибо за то, что я моя резиновая утка.

Чтобы быть понятным, метод LoadRelated теперь выглядит так

public static IQueryable<ToBeLoaded> LoadRelated(this DbSet<ToBeLoaded> toBeLoadedSet)
{
    return toBeLoadedSet.Include(tbl => tbl.Bases);
}
...