【问题标题】:Entity Framework 6 - include derived type child propertyEntity Framework 6 - 包括派生类型子属性
【发布时间】:2017-03-21 22:49:23
【问题描述】:

我的架构包括:

  • Lo​​anApplication(父对象)
  • Borrowers(作为派生类型 BusinessBorrowerIndividual 的子对象)
  • BorrowersOwnerManagers(多对多,我必须明确定义它,因为它具有自定义审计属性)
  • OwnerManager(与借款人多对多关系的一部分)
  • OwnerManagerIndividual(派生自 OwnerManager 的类型)
  • OwnerManagerBusiness(派生自 OwnerManager 的类型)
  • OwnerManagerIndividualsRaceTypes(多对多,我必须明确定义它,因为它具有自定义审核属性)
  • RaceType(与 OwnerManagerIndividual 的多对多关系的一部分)

我尝试在我的 LoanApplication 存储库中使用以下内容:

public ILoanApplication GetById(int id)
{
    ILoanApplication item;


    using (var db = new MainContext())
    {
        item = db.LoanApplications
            .Include(c => c.Borrowers)
            .Include(c => c.Borrowers.Select(b => b.BusinessBorrowerIndividual))
            .Include(c => c.Borrowers.Select(b => b.BorrowersOwnerManagers))
            .Include(c => c.Borrowers.Select(b => b.BorrowersOwnerManagers.Select(bb => bb.OwnerManager)))
            .Include(c => c.Borrowers.Select(b => b.BorrowersOwnerManagers.Select(bb => bb.OwnerManager)
                                                                                            .OfType<OwnerManagerIndividual>()
                                                                                            .Select(o => o.OwnerManagerIndividualsRaceTypes)))
            .FirstOrDefault(l => l.Id == id);
    }

    return item;
}

除了最后一个包含之外,一切都有效。我使用它时收到以下错误:

包含路径表达式必须引用导航属性 在类型上定义。使用虚线路径进行参考导航 属性和用于集合导航的 Select 运算符 特性。参数名称:路径

如何更新,以便我可以包含 OwnerManagerIndividual 类型的 OwnerManager 对象的 OwnerManagerIndividualsRaceTypes 属性?我还想包含所有 OwnerManger 对象,无论它们是 OwnerManagerIndividual 还是 OwnerManagerBusiness。

** 更新 ** 根据回复,似乎无法在一次通话中轻松完成。我建议进行二次调用来填充,这不是优雅的解决方案:

public ILoanApplication GetById(int id)
{
    var ownerManagerIndividualRepository = new OwnerManagerIndividualRepository(UserOrProcessName);
    ILoanApplication item;


    using (var db = new MainContext())
    {
        item = db.LoanApplications
            .Include(c => c.Borrowers)
            .Include(c => c.Borrowers.Select(b=> b.BusinessBorrowerIndividual))
            .Include(c => c.Borrowers.Select(b => b.BorrowersOwnerManagers))
            .Include(c => c.Borrowers.Select(b => b.BorrowersOwnerManagers.Select(bb => bb.OwnerManager)))
            .FirstOrDefault(l => l.Id == id);
    }

    if (item?.Borrowers?.Count > 0 &&
        item.Borrowers.FirstOrDefault().BorrowersOwnerManagers.Any(o => o.OwnerManager.IsIndividual))
    {
        foreach (var owners in item.Borrowers.FirstOrDefault().BorrowersOwnerManagers.Where(o => o.OwnerManager.IsIndividual))
        {
            var owner = ownerManagerIndividualRepository.GetById(owners.OwnerManager.Id.Value);

            foreach (var type in owner.OwnerManagerIndividualsRaceTypes)
            {
                ((OwnerManagerIndividual)owners.OwnerManager).OwnerManagerIndividualsRaceTypes.Add((OwnerManagerIndividualsRaceTypes)type);
            }
        }
    }


    return item;
}

【问题讨论】:

  • 您是否意识到您每次都会获得不同的 BusinessBorrowersOwnerManagers 实例?我认为您应该在单独的查询中获取最后一点,构建字典并手动附加它们
  • 很遗憾,您无法在 Include 中进行过滤,这意味着您无法包含派生实体的属性。
  • 我添加了一个更新的部分来反映第二次调用,这不是一个优雅的解决方案,但它似乎工作。

标签: c# entity-framework entity-framework-6


【解决方案1】:

.Include() 扩展只有一个目的:急切地加载属性,而不是让它们延迟加载。这只是查询构建器在 SQL 中包含JOINs 的一个选项,而不是其他任何东西。

您试图在 Include 表达式中提供过滤,这是错误的。

至于如何实际实现内部集合的过滤部分,我不确定在 EF 中使用单个查询是否可以轻松实现,您可以查看类似的问题,例如 How to filter nested collection Entity Framework objects?

【讨论】:

  • .Include() 不支持 OfType 吗?
  • @Josh 没错。只有属性路径和Selects。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多