繁体   English   中英

嵌套 tph 继承成员的 ef-core 负载集合属性

[英]ef-core load collection property of nested tph inherited member

鉴于以下类结构

 public class Parent 
    {
        public Guid Id { get; 
        public List<BaseChild> Children { get; set; }
    }

 public abstract class BaseChild
    {
        public int Id { get; set; }
        public string ChildName { get; set; }
    }

public class NormalChild : BaseChild
    {
         public DateTime BirthDate { get; set; }
    }

public class RichChild : BaseChild
    {
        public List<OffshoreAccount> OffshoreAccounts { get; set; }
    }

public class OffshoreAccount 
    {
        public string AccountNumber { get; set; }
        public AccountInfo AccountInfo { get; set; }
    }

查询父数据以包含有关孩子的离岸帐户信息的最佳方法是什么? 我想出了下面的解决方案,使用 ef-core 的显式加载,但感觉不对。 有没有更优雅的解决方案?

var parent = Context.Set<Parent>()
    .Where(o => o.Id == Guid.Parse(parentId))
    .Include(o => o.Children)
    .SingleOrDefault();

foreach (var child in parent.Children.OfType<RichChild>())
    {
        Context.Entry<RichChild>(child).Collection(f => f.OffshoreAccounts).Load();
        foreach (var account in child.OffshoreAccounts)
            {
                 Context.Entry<OffshoreAccount>(account).Reference(f => f.AccountInfo).Load();
            }
     }

更新(EF Core 2.1+):

从 v2.1 开始,EF Core 本机支持通过 C# 强制转换或as运算符在派生类型上包含

例如

.Include(e => e.Children)
    .ThenInclude(e => ((RichChild)e).OffshoreAccounts)
        .ThenInclude(e => e.AccountInfo)

或者

.Include(e => e.Children)
    .ThenInclude(e => (e as RichChild).OffshoreAccounts)
        .ThenInclude(e => e.AccountInfo)

该文档声称也可以使用Include coudld 的string重载,例如根据它

.Include(e => "Children.OffshoreAccounts.AccountInfo")

也应该工作,但它没有(检查到 v3.1.4)。

原来的:

目前无法在父查询中实现这一点,但可以通过使用EntryCollectionQueryInclude / ThenIncludeLoad调用的组合来改进显式加载:

var parent = Context.Set<Parent>()
    .Where(o => o.Id == Guid.Parse(parentId))
    .Include(o => o.Children)
    .SingleOrDefault();

Context.Entry(parent).Collection(e => e.Children)
    .Query().OfType<RichChild>()
    .Include(e => e.OffshoreAccounts)
        .ThenInclude(e => e.AccountInfo)
    .Load();

在当前的 EFCore (2.1.1) 中,您可以在ThenInclude使用类型转换来获得您正在寻找的结果:

var parent = _context.Set<Parent>()
                 .Include(x => x.Children)
                 .ThenInclude(y => (y as RichChild).OffshoreAccounts)
                 .SingleOrDefault();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM