Registering records in Linq in one column?

enter image description here

I want a result like

Test Genre1/
Test Genre2/
Test Genre3/Test genre1               //(Bcoz id 1 as Test Genre1)
Test Genre4/Test genre2               //(Bcoz id 2 as Test Genre2)
Test genre1/Test Test genre3/Genre5   //(Bcoz id 3 as Test Genre3)

      

It should be a combination id

and parent id

in Linq

.

Any help would be appreciated ...

+3


source to share


3 answers


Create a recursive function and use this function in your linq. something like that.



//Recursive method
 private static string GetParentPath( IEnumerable<Item> items , Item item )
    {
        if (item.ParentId.HasValue)
        {
            return GetParentPath(items, items.First(i => i.Id == item.ParentId)) + "/" + item.GenreName;
        }

        return item.GenreName;
    }



var items = new Item[]
        {
            new Item {Id = 1, GenreName = "Test Genre 1", ParentId = null},
            new Item {Id = 2, GenreName = "Test Genre 2", ParentId = null},
            new Item {Id = 3, GenreName = "Test Genre 3", ParentId = 1},
            new Item {Id = 4, GenreName = "Test Genre 4", ParentId = 2},
            new Item {Id = 5, GenreName = "Test Genre 5", ParentId = 3}
        };



 // Linq query
        var result = from child in items
                  select new { Path = GetParentPath(items, child) };



    //Class used in example
 public class Item
    {
        public int Id { get; set; }

        public string GenreName { get; set; }

        public int? ParentId { get; set; }
    }

      

0


source


You can try a recursive method that returns IEnumerable

defined in the entity class:

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

    public IEnumerable<Genre> GetSelfAndAncestors(IEnumerable<Genre> items)
    {
        yield return this;

        if (ParentId.HasValue)
        {
            var parent = items.First(x => x.Id == ParentId.Value);

            foreach (var ancestor in parent.GetSelfAndAncestors(items))
            {
                yield return ancestor;
            }
        }
    }
}

      

Using:



var genres = new[]
{
    new Genre {Id = 1, Name = "Test Genre 1", ParentId = null},
    new Genre {Id = 2, Name = "Test Genre 2", ParentId = null},
    new Genre {Id = 3, Name = "Test Genre 3", ParentId = 1},
    new Genre {Id = 4, Name = "Test Genre 4", ParentId = 2},
    new Genre {Id = 5, Name = "Test Genre 5", ParentId = 3}
};

foreach (var genre in genres)
{
    var path = genre.GetSelfAndAncestors(genres);
    Console.WriteLine(String.Join("/", path.Select(x => x.Name)));
}

      

If the tree is deep, you may notice a significant performance improvement comparing this implementation to non-t20>.

+1


source


Given a method to be called recursively that

  • Adds name to string
  • Calls itself recursively with any existing parent

private static string SelectGenreName(IEnumerable<Genre> all, Genre g)
{
    var s = g.Name + '/';
    if(g.ParentId.HasValue){
        s += SelectGenreName(all, all.Single(x => x.Id == g.ParentId.Value));   
    }
    return s;
}

      

The code to get a reasonable result * is pretty simple:
* reasonable result; Your last example has been reversed from the previous 4. The above results give your first four examples. those.Child/Parent/Grandparent

var genres = new[]
{
    new Genre {Id = 1, Name = "Test Genre 1", ParentId = null},
    new Genre {Id = 2, Name = "Test Genre 2", ParentId = null},
    new Genre {Id = 3, Name = "Test Genre 3", ParentId = 1},
    new Genre {Id = 4, Name = "Test Genre 4", ParentId = 2},
    new Genre {Id = 5, Name = "Test Genre 5", ParentId = 3}
};

var result = genres.Select(g => SelectGenreName(genres,g));

foreach(var r in result)
    Console.WriteLine(r);

      

Live example: http://rextester.com/MXQUH43732

+1


source







All Articles