简体   繁体   中英

Linq to Sql multiple outer joins

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.

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?

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 {
          };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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