1

My schema includes:

  • LoanApplication (parent object)
  • Borrowers (child object that as derived type BusinessBorrowerIndividual)
  • BorrowersOwnerManagers (many-to-many, I have to explicitly define it because it has custom audit properties)
  • OwnerManager (part of many-to-many relationship with Borrowers)
  • OwnerManagerIndividual (derived type from OwnerManager)
  • OwnerManagerBusiness (derived type from OwnerManager)
  • OwnerManagerIndividualsRaceTypes (many-to-many, I have to explicitly define it because it has custom audit properties)
  • RaceType (part of many-to-many relationship with OwnerManagerIndividual)

I tried using the following in my repository for 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;
}

Everything works except for the last include. I receive the following error when I use it:

The Include path expression must refer to a navigation property defined on the type. Use dotted paths for reference navigation properties and the Select operator for collection navigation properties. Parameter name: path

How do I update so that I can include the OwnerManagerIndividualsRaceTypes properties for the OwnerManager objects that are of OwnerManagerIndividual type? I also want to include all OwnerManger objects, regardless of if they are OwnerManagerIndividual or OwnerManagerBusiness.

** Update ** Based on the responses, it appears it can't easily be done in a single call. I going with the suggestion to make a secondary call to populate, which isn't as elegant solution:

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;
}
Josh
  • 8,219
  • 13
  • 76
  • 123
  • You do realise you will get a different instance of BusinessBorrowersOwnerManagers every single time? I think you should be getting the last bit in a separate query, build a dictionary and manually attach them – Michal Ciechan Mar 21 '17 at 23:00
  • Unfortunately you can't filter in an `Include`, which means you can't include the properties of a derived entity. – DavidG Mar 21 '17 at 23:14
  • I added an Updated section to reflect making second call, not a elegant solution, but it appears to work. – Josh Mar 22 '17 at 13:20

1 Answers1

1

.Include() extension serves just single purpose: load properties eagerly instead of leaving them for lazy loading. That's just an option for query builder to include JOINs in SQL, not anything else.

You are trying to provide filtering inside Include expression, which is wrong.

As for how to actually achieve filtering part of inner collection I'm not sure that's easily doable with single query in EF, you can check similar question for example How to filter nested collection Entity Framework objects?

Community
  • 1
  • 1
Lanorkin
  • 7,310
  • 2
  • 42
  • 60