基于条件递归生成列表

niwlg2el  于 2021-08-01  发布在  Java
关注(0)|答案(1)|浏览(310)

我有一个包含子订单等的订单列表。它们通过childorderid和orderid链接。但是,在每个订单中都有通过pid和parentpid链接的产品和子产品。然而,并不是每个产品都有子产品。
我附上了db中数据的示例屏幕截图,以说明我的意思和我希望实现的目标。我遇到的问题是,我需要将这个平面文件结构放入一个嵌套的c#列表中。每个bomlineclass都有一个bomlineclass的列表

var navigationItems = bomline.Select(
                        i => new BOMLineClass
                        {
                            ParentOrderID = i.ParentOrderID,
                            BSOOrderNo = i.BSOOrderNo,
                            BSODemandDate = i.BSODemandDate,
                            OrderTypeDesc = i.OrderTypeDesc,
                            OrderType = i.OrderType,
                            BuildRef = i.BuildRef,
                            HasSubAssembly = i.HasSubAssembly,
                            ChildOrderID= i.ChildOrderID,
                            ChildOrderNo= i.ChildOrderNo,
                            OrderID = i.OrderID,
                            OrderLineID = i.OrderLineID,
                            ProductCode = i.ProductCode,
                            ParentPID = i.ParentPID,
                            PID = i.PID,
                        }
                    ).ToList();

                        foreach (var i in navigationItems)
                        {
                            i.BOMLines = navigationItems.Where(n => n.ChildOrderID== i.OrderID).ToList();

                            foreach (var x in i.BOMLines)
                            {
                                //Thought I could link the children via the product ID and parent product Id here
                            }

                        }

                        List<BOMLineClass> rootNavigationItems2 = navigationItems.Where(n => n.ChildOrderID == false).ToList();

                        bh.BOMLines = rootNavigationItems2;

我已经挣扎了至少5天了。

6rqinv9w

6rqinv9w1#

看看下面是否有用。您必须从childorderid为null的leaf开始,一直到root。您还需要有兄弟节点和子节点。参见下面的代码

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static DataTable dt = new DataTable();
        static void Main(string[] args)
        {
            dt.Columns.Add("ChildOrderID", typeof(int));
            dt.Columns.Add("ChildOrderNo", typeof(string));
            dt.Columns.Add("OrderID", typeof(int));
            dt.Columns.Add("OrderLineID", typeof(int));
            dt.Columns.Add("ProductCode", typeof(string));
            dt.Columns.Add("PID", typeof(int));
            dt.Columns.Add("ParentPID", typeof(int));

            dt.Rows.Add(null, null, 40551, 193085, "BP6FS", 261649, 303032);
            dt.Rows.Add(null, null, 40551, 193086, "HT1-BP", 299119, 303032);
            dt.Rows.Add(40551, "BSOMSO20022DDT_1_2", 40550, 193083, "AG947", 253420, 290961);
            dt.Rows.Add(40551, "BSOMSO20022DDT_1_2", 40550, 193084, "JS10", 303032, 290961);
            dt.Rows.Add(40550, "BSOMSO20022DDT_1", 40549, 193081, "CA9680", 266226, 269143);
            dt.Rows.Add(40550, "BSOMSO20022DDT_1", 40549, 193082, "FU552-BP", 290961, 3269143);

            List<BOMLineClass> navigationItems = BOMLineClass.GroupBOM(dt);
            foreach (BOMLineClass order in navigationItems)
            {
                BOMLineClass.Print(order, 0);
            }
            Console.ReadLine();
        }

    }
    public class BOMLineClass
    {
        public int ParentOrderID { get;set;}
        public string BSOOrderNo { get;set;}
        public DateTime BSODemandDate { get;set;}
        public string OrderTypeDesc { get;set;}
        public string OrderType { get;set;}
        public string BuildRef { get;set;}
        public string HasSubAssembly { get;set;}
        public int? ChildOrderID { get;set;}
        public string ChildOrderNo { get;set;}
        public int OrderID { get;set;}
        public int OrderLineID { get;set;}
        public string ProductCode { get;set;}
        public int ParentPID { get;set;}
        public int PID { get; set; }
        public List<BOMLineClass> children { get; set; }
        public List<BOMLineClass> siblings { get; set; }

        static DataTable dt;
        public static List<BOMLineClass> GroupBOM(DataTable dt)
        {
            BOMLineClass.dt = dt;
            List<BOMLineClass> leafOrders = new List<BOMLineClass>();

            foreach(DataRow row in dt.AsEnumerable().Where(x => x.Field<int?>("ChildOrderID") == null))
            {
                leafOrders.Add(AddFields(row));
            }
            return GroupBOMRecursive(leafOrders); 

        }
        static List<BOMLineClass> GroupBOMRecursive(List<BOMLineClass> childOrders)
        {
            List<BOMLineClass> orders = new List<BOMLineClass>();

            var groups = childOrders.GroupBy(x => x.OrderID).ToList();
            Boolean hasParents = false;

            foreach (var group in groups)
            {
                //find parent datarow
                List<DataRow> parentRow = dt.AsEnumerable().Where(x => x.Field<int?>("ChildOrderID") == group.Key).ToList();
                if (parentRow.Count == 0)
                {
                    //no parent
                    orders.Add(group.First());
                }
                else
                {
                    hasParents = true;
                    BOMLineClass order = null;
                    for (int i = 0; i < parentRow.Count; i++)
                    {
                        if (i == 0)
                        {
                            order = AddFields(parentRow[i]);
                            order.children = new List<BOMLineClass>();
                            order.children.AddRange(group);
                            orders.Add(order);
                        }
                        else
                        {
                            if (order.siblings == null) order.siblings = new List<BOMLineClass>();
                            order.siblings.Add(AddFields(parentRow[i]));
                        }
                    }
                }
            }
            if (hasParents)
            {
                return GroupBOMRecursive(orders);
            }
            else
            {
                return orders;
            }
        }
        static public BOMLineClass AddFields(DataRow row)
        {
            BOMLineClass order = new BOMLineClass();
            order.ChildOrderID = row.Field<int?>("ChildOrderID");
            order.ChildOrderNo = row.Field<string>("ChildOrderNo");
            order.OrderID = row.Field<int>("OrderID");
            order.OrderLineID = row.Field<int>("OrderLineID");
            order.ProductCode = row.Field<string>("ProductCode");
            order.PID = row.Field<int>("PID");
            order.ParentPID = row.Field<int>("ParentPID");
            return order;
        }

        public static void Print(BOMLineClass order, int level)
        {
            const int IDENT = 10;
            Console.WriteLine("{0}{1}({2})", new string('-', IDENT * level), order.OrderID, order.ParentPID);
            if (order.siblings != null)
            {
                foreach (BOMLineClass sibling in order.siblings)
                {
                    Console.WriteLine("{0}{1}({2})", new string('-', IDENT * level), sibling.OrderID, sibling.ParentPID);
                }
            }
            if (order.children != null)
            {
                foreach (BOMLineClass child in order.children)
                {
                    Print(child, level + 1);
                }
            }
        }
   }

}

相关问题