简体   繁体   English

按父项和子项排序的列表

[英]Order list by parent and child items

I have a list of products that have to be ordered by parent then all children of that parent, then next parent, etc.我有一个必须由父母订购的产品列表,然后是该父母的所有孩子,然后是下一个父母,等等。

Product One
    Child One
    Child Two
Product Two
    Child One

These products are all in one table with a parent id field, the child products have a parent id but the parent items can have a null parent (indicating that product is a top level product)这些产品都在一个表中,有一个父 id 字段,子产品有一个父 id,但父项可以有一个 null 父项(表明该产品是顶级产品)

样品表

I was thinking something like the following:我在想类似以下的事情:

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);
}

Any suggestions on how I would do this a little cleaner?关于我如何做得更干净的任何建议?

Given "Parent" is nullable property (assuming nullable int here).鉴于“Parent”是可为空的属性(假设这里的 int 可为空)。 Following should give you parent-child related ordered list:以下应该给你父子相关的有序列表:

 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();

you could try something like that.你可以尝试这样的事情。 Assuming parent is a nullable:假设 parent 是可空的:

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

if its a string:如果它是一个字符串:

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

You could do it this way:你可以这样做:

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

I don't know if it's more cleaner but if you want a unique linq instruction you can try this :我不知道它是否更干净,但如果你想要一个独特的 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();

You should add a ParentId to the Product One and Product two, and the, will be easier to solve it.您应该将 ParentId 添加到产品一和产品二,这样会更容易解决。 If Parent One is 1, and Parent Two is 2, only do this如果父一为 1,父二为 2,则只执行此操作

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

Maybe using linq this way:也许以这种方式使用 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 };

It's very easy and complicated way, In 'res' variable you'll see this kind of situation - parent1 > child.1.1 > child.1.2 > parent2 > child.2.1 > child.2.2 > child.2.3 > parent3:这是非常简单和复杂的方式,在“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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM