按父项和子项列出的订单列表

时间:2014-02-27 15:04:35

标签: c# .net linq

我有一个产品清单,必须由父母订购,然后是该父母的所有子女,然后是下一位父母等。

Product One
    Child One
    Child Two
Product Two
    Child One

这些产品都在一个包含父ID字段的表中,子产品具有父ID,但父项可以具有空父项(表示该产品是顶级产品)

Sample table

我在考虑以下内容:

var list = GetProductList();
var newList = new List<ProductDTO>();

var parents = from p in list
    where p.Parent == null
    select p.Id;


foreach (var parent in parents)
{
    var tempList = new List<ProductDTO>();
    tempList.Add(list.FirstOrDefault(x => x.Id == parent));
    tempList.AddRange(list.Where(x => x.Parent == parent).OrderBy(x => x.Id));
    newList.AddRange(tempList);
}

关于我如何做一点清洁工作的任何建议?

7 个答案:

答案 0 :(得分:4)

给定“Parent”是可以为空的属性(假设这里为nullable)。以下内容应该为您提供与子女相关的有序列表:

 public class ProductDTO
 {
     public int Id { get; set; }
     public string Name { get; set; }
     public int? Parent { get; set; }
 }

 var products = new List<ProductDTO>();
 products.Add(new ProductDTO() { Id = 1, Name = "Product One" });
 products.Add(new ProductDTO() { Id = 2, Name = "Product Two" });
 products.Add(new ProductDTO() { Id = 3, Name = "Product Three" });
 products.Add(new ProductDTO() { Id = 4, Name = "Child One", Parent=1 });
 products.Add(new ProductDTO() { Id = 5, Name = "Child Two", Parent = 2 });
 products.Add(new ProductDTO() { Id = 6, Name = "Child One", Parent = 1 });

var ordered = products
                .Where(p => p.Parent == null)
                .OrderBy(p=> p.Id)
                .Select(p => products
                    .Where(c => c.Parent == p.Id)
                    .OrderBy(c => c.Id))
                .ToList();

答案 1 :(得分:1)

你可以尝试类似的东西。假设父是可以为空的:

var sorted = list.OrderBy(x => x.parent ?? x.id).ThenBy(x=>x.id);

如果是一个字符串:

            var sorted = list.OrderBy(x =>
            {
                if (x.parent == "null")
                    return x.id;
                else
                    return Convert.ToInt32(x.parent);
            }).ThenBy(x => x.id);

答案 2 :(得分:1)

你可以这样做:

list.ForEach(item => 
            {
                if (item.Parent == null)
                {
                    orderedList.Add(item);
                    orderedList.AddRange(list.Where(child => child.Parent == item.Id));
                }
            });

答案 3 :(得分:1)

我不知道它是否更清洁,但如果你想要一个独特的linq指令,你可以试试这个:

var result = GetProductList().Where(p => p.Parent == null)
                             .SelectMany(p => list.Where(c => c.Parent == p.Id)
                                                  .Concat(new[] { p })
                                                  .OrderBy(c => c.Parent.HasValue)
                                                  .ThenBy(c => c.Id)
                                                  .ToList())
                             .ToList();

答案 4 :(得分:0)

您应该将ParentId添加到Product One和Product 2,并且更容易解决它。 如果Parent One为1,Parent Two为2,则只执行此操作

var result = parents.OrderBy(x => x.Parent).ThenBy(x => x.Id);

答案 5 :(得分:0)

也许以这种方式使用linq:

var groupList = from c in products
                where c.Parent.HasValue
                group c by c.Parent into r
                join p in products on r.Key equals p.Id
                orderby p.Name
                select new { Parent = p, Children = r };

答案 6 :(得分:-1)

这是非常简单和复杂的方式,在'res'变量中你会看到这种情况 - parent1 > child.1.1 > child.1.2 > parent2 > child.2.1 > child.2.2 > child.2.3 > parent3:

        //items is a list of unsorted objects
       
        var res = items.OrderBy(x =>
        {
            if (x.ParentId == null)
                return x.Id;
            else
                return x.ParentId;
        }).ThenBy(t => t.Id);