Search code examples
c#.netentity-frameworklinqlinq-to-entities

Linq to Entities query for hierarchy


I have this table:

CREATE TABLE [md].[Services]
(
    [id] [nvarchar](36) NOT NULL,
    [Value] [nvarchar](500) NOT NULL,
    [Parentid] [nvarchar](36) NULL,
    [Status] [nvarchar](10) NOT NULL
)

I wrote a query to get a flattened view of the data like so:

SELECT
    bottomLevel.id as [Bot],
    midLevel.id as [Mid], 
    topLevel.id as [Top]
FROM
    md.Services bottomLevel
LEFT OUTER JOIN 
    md.Services midLevel ON bottomLevel.Parentid = midLevel.id
LEFT OUTER JOIN
    md.Services topLevel ON midLevel.Parentid = topLevel.id

But for the life of me I can't seem to figure out the LINQ version of this with EF.

I came up with this but it returns way more rows, and I haven't yet figured out what I'm missing... Any thoughts?

var query = (from level3 in _db.Services
             from level2 in _db.Services
                               .Where(x => x.Parentid == level3.id).DefaultIfEmpty()
             from level1 in _db.Services
                               .Where(x => x.Parentid == level2.id).DefaultIfEmpty()
             select new
                    {
                        Bot = level3.id,
                        Mid = level2.id,
                        Top = level1.id,
                    });

Solution

  • I figured it out. I had a few things missing and I was doing it backwards...

    var query2 = (
                    from level1 in db.ServiceTypes
                    join s1 in db.ServiceTypes on level1.ParentGuid equals s1.Guid into q1
                    from level2 in q1.DefaultIfEmpty()
                    join s2 in db.ServiceTypes on level2.ParentGuid equals s2.Guid into q2
                    from level3 in q2.DefaultIfEmpty()
                    select new
                    {
                        BottomGuid = level1.Guid,
                        MidGuid = level2.Guid,
                        TopGuid = level3.Guid,
                    }
    
                );