实体框架6 - 包括派生类型子属性

时间:2017-03-21 22:49:23

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

我的架构包括:

  • LoanApplication(父对象)
  • 借款人(派生类型为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;
}

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

  

Include路径表达式必须引用导航属性   在类型上定义。使用虚线路径进行参考导航   属性和集合导航的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;
}

1 个答案:

答案 0 :(得分:1)

.Include()扩展仅用于单一目的:急切地加载属性而不是让它们进行延迟加载。这只是查询构建器在SQL中包含JOIN的选项,而不是其他任何选项。

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

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