Nested object to hierarchical object list I have a C# type to generate Layer SubLayer:

public class Layer
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
}


And simulated a list with a Db class:

public static class Db
    {
        public static IList&lt;Layer&gt; GetLayers()
        {
            return new List&lt;Layer&gt;
                   {
                       new Layer{Id = 1, ParentId = 0, Name = "First Layer" },
                       new Layer{Id = 2, ParentId = 1, Name = "First SubLayer1" },
                       new Layer{Id = 3, ParentId = 1, Name = "First SubLayer2" },
                       new Layer{Id = 4, ParentId = 1, Name = "First SubLayer3" },
                       new Layer{Id = 5, ParentId = 0, Name = "Second Layer" },
                       new Layer{Id = 6, ParentId = 5, Name = "Second SubLayer1" },
                       new Layer{Id = 7, ParentId = 5, Name = "Second SubLayer2" },
                       new Layer{Id = 8, ParentId = 7, Name = "Sub -3" }
                   };
        }
    }


I want to get a serialized JSON object, so I created a service class to generate and changed the Layer class:

public class Layer
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public IList&lt;Layer&gt; ChildLayers { get; set; }

    public Layer()
    {
        ChildLayers = new List&lt;Layer&gt;();
    }
}

public class LayerService
{
    public IList&lt;Layer&gt; GetLayers()
    {
        IList&lt;Layer&gt; data = Db.GetLayers();

        IList&lt;Layer&gt; hierarcy = new List&lt;Layer&gt;();

        foreach (var layer in data)
        {
            var layer1 = layer;

            var sublayers = data.Where(i =&gt; i.ParentId == layer1.Id &amp;&amp; i.ParentId !=0);

            var enumerable = sublayers as Layer[] ?? sublayers.ToArray();

            if(enumerable.Any() &amp;&amp; layer.ParentId ==0)
                hierarcy.Add(layer);

            foreach (var sublayer in enumerable)
            {
                layer.ChildLayers.Add(sublayer);    
            }
        }

        return hierarcy;
    }
}


But this LayerService code is ugly. Is there any practical way with Linq or else? Is there a cleaner way?
var sublayers = data.Where(i =&gt; i.ParentId == layer1.Id &amp;&amp; i.ParentId !=0);  



you should let the operators some room to breathe. Adding a space after = makes your code more readable.  

Bug alert  

In the above query you are filtering for i.ParentId != 0 and later on you have the condition &amp;&amp; layer.ParentId ==0 so your hierarchy wil remain empty.  




var enumerable = sublayers as Layer[] ?? sublayers.ToArray();  



This makes me just wonder. What sense does it have to convert the IEnumerable&lt;Layer&gt; to an array if the next thing you do is iterating over the items by using a foreach loop ? 


var layer1 = layer;  



this isn't necessary at all, it is sufficient to use the layer inside linq expression.  



You should always use braces {} for single command if statements to make your code less error prone. If you decide to no use them, please don't come back whining that you have a bug you can't find (humour btw.).



Integrating the mentioned points will lead to  

public IList&lt;Layer&gt; GetLayers()
{
    IList&lt;Layer&gt; data = Db.GetLayers();

    IList&lt;Layer&gt; hierarcy = new List&lt;Layer&gt;();

    foreach (var layer in data)
    {

        var sublayers = data.Where(i =&gt; i.ParentId == layer.Id &amp;&amp; i.ParentId != 0);

        if (sublayers.Any())
        {
            hierarcy.Add(layer);
        }
        foreach (var sublayer in sublayers)
        {
            layer.ChildLayers.Add(sublayer);
        }
    }

    return hierarcy;
}  





public class Layer
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public IList&lt;Layer&gt; ChildLayers { get; set; }

    public Layer()
    {
        ChildLayers = new List&lt;Layer&gt;();
    }
}  



You shouldn't expose the ChildLayers property setter to the public. If someone comes along setting it to null you would be lost. 

You should just change it to  

public IList&lt;Layer&gt; ChildLayers { get; private set; }  


Otherwise using autoimplemented properties, as long as you don't need validation in the setters , is the way to go.