Joe
Joe

Reputation: 6416

Nested Object from DataTable

I feel like I am way off track here. I have been banging my head against my keyboard and I do not feel like I am any closer to a solution. Guidance would be much appreciated.

Models.Content contains a SubContent property that is of type List<Models.Content>. The nesting could be infinite and should be recursive. I feel like this should be able to be done with a few lines of LINQ and while or something to that affect. I have created a mess.

private static List<Models.Content> GetAllContentFromDataSet(DataSet ds)
{
    var content = new List<Models.Content>();
    var contentList = (from DataRow row in ds.Tables[0].Rows
                       select new Models.Content
                       {
                           Id = Convert.ToInt32(row["Id"]),
                           ParentContentId = Convert.ToInt32(row["ParentContentId"]),
                           c3 = Convert.ToString(row["c3"]),
                           c4 = Convert.ToString(row["c4"]),
                           c5 = Convert.ToString(row["c5"])
                       }).ToList();

    content.AddRange(NestContent(contentList));

    return content;
}

private static IEnumerable<Models.Content> NestContent(List<Models.Content> content)
{
    var toBeRemoved = new List<Models.Content>();

    foreach (var c in content)
    {
        var parent = content.FirstOrDefault(p => p.Id == c.ParentContentId);
        if (parent == null) continue;
        parent.SubContent.Add(c);
        toBeRemoved.Add(c);
    }

    foreach (var c in toBeRemoved)
    {
        content.Remove(c);
    }

    return content;
}

Upvotes: 0

Views: 1748

Answers (2)

jmcilhinney
jmcilhinney

Reputation: 54487

Here's an example of what I would do:

// Create a list of all items without children.
var things = table.AsEnumerable()
                  .Select(row => new Thing
                  {
                      Id = row.Field<int>("Id"),
                      ParentId = row.Field<int>("ParentId")
                  })
                  .ToList();

// Add children to each item.
things.ForEach(t1 => t1.Children = things.Where(t2 => t2.ParentId == t1.Id).ToList());

// Create a list of items that don't have a parent..
things = things.Where(t => t.ParentId == 0).ToList();

Upvotes: 3

Leo
Leo

Reputation: 14860

I agree, I think you could build your model hierarchy with fewer lines of code, thus, making your code easier to maintain and read. I'd actually do this in two steps...

  1. Parsing the root "content" first (those with ParentContentId == null...I guess)...this can be done in one line of code with LINQ
  2. Then iterate through all child content rows (those with a ParentContentId specified) and "attach" them to the parent content (if exists)

Let me know if you got the idea or if you need an example

Upvotes: 0

Related Questions