0

Thanks in advance for any help. Not an expert in Linq to Sql by any means. I have 4 tables.

The main lb_item table which defines, unsurprisingly, an item. Many fields but holds 3 ID fields. itemID (key) categoryID (not null) patternID (can be null)

lb_pattern table which is keyed off the lb_item patternID.

lb_category table which is keyed off the lb_item categoryID.

lb_animal table which is keyed off the lb_item item ID.

So I need a select from the lb_item table joining to these other 3 tables to bring back varchar fields as I'm building a DTO.

A single left outer join works fine thus:

from lbi in lbContext.lb_item
            join lbp in lbContext.lb_pattern on lbi.patternID equals lbp.patternID into g1
            from j1 in g1.DefaultIfEmpty()
            join lbc in lbContext.lb_category on lbi.categoryID equals lbc.categoryID
            where lbi.itemID == id
            select new lb_itemDTO..........

I now need to add a 2nd left outer join for the lb_animal table. So I started to do this:

from lbi in lbContext.lb_item
            join lbp in lbContext.lb_pattern on lbi.patternID equals lbp.patternID into g1
            from j1 in g1.DefaultIfEmpty()
            join lba in lbContext.lb_animal on j1.

But the options in VS for j1 give me only the fields within the lb_pattern table. I need the join to read:

join lba in lbContext.lb_animal on j1.itemID equals lba.itemID

or

join lba in lbContext.lb_animal on lbi.itemID equals lba.itemID

Neither works and gives me an exception along the lines of "'NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core".

So how can I add a left outer join to the lb_animal table?

I've spent the last hour looking at various SO posts to suss it out but I just cannot seem to get my head around the solution for some reason. Feel like a newbie. And I'm sure the solution is going to be obvious!

Any help or pointers to a solution would be much appreciated.

stumcc
  • 185
  • 1
  • 11

2 Answers2

0

Persvered and finally came across a SO post which approached it in a different way and it worked. Original SO is here:

My working code is now thus:

from lbi in lbContext.lb_item
            from lbc in lbContext.lb_category
              .Where(c => c.categoryID == lbi.categoryID)
            from lbp in lbContext.lb_pattern
              .Where(p => p.patternID == lbi.patternID)
              .DefaultIfEmpty()
            from lba in lbContext.lb_animal
              .Where(a => a.itemID == lbi.itemID)
              .DefaultIfEmpty()
            where lbi.itemID == id
            select new lb_itemDTO

Would still be interested in comments on this solution as it's not breaking the outer joins into grouped segments. So is this solution I found any less efficient in terms of the SQL it generates compared to how I was originally proposing to do it?

stumcc
  • 185
  • 1
  • 11
  • My tests indicate this should generate the exact same SQL as the full fluent version I posted, and so should perform the same (EF 3.1). – NetMage Nov 09 '20 at 20:33
0

This should work:

var ans = from lbi in lbContext.lb_item
          where lbi.itemID == id
          join lbp in lbContext.lb_pattern on lbi.patternID equals lbp.patternID into lbpj
          from lbp in lbpj.DefaultIfEmpty()
          join lba in lbContext.lb_animal on lbi.itemID equals lba.itemID into lbaj
          from lba in lbaj.DefaultIfEmpty()
          join lbc in lbContext.lb_category on lbi.categoryID equals lbc.categoryID
          select new {
          };
NetMage
  • 26,163
  • 3
  • 34
  • 55
  • Thanks for the answer. As you will see I did work it out myself. But. Can you tell me if your solution has any performance benefits in the way it generates the SQL over the solution I implemented? I'm not a big SO player so not bothered about giving myself the credit for an answer. But what I do like to do is learn. So if you can be bothered, an elaboration on your answer would be appreciated. Thanks again for taking the time to respond. – stumcc Nov 08 '20 at 16:54