什么是迭代或嵌套嵌套对象集合的更有效或更有效的方法

时间:2019-01-10 15:52:26

标签: c# linq iteration

我正在从SQL的BOM表项目(物料清单)的扁平列表中构建嵌套层次结构的对象,这些清单包含BOM表级别及其所属的父级。基本上,由较小子部件组成的每个父级都需要将其子部件添加到该对象内的集合中。我相信我们有些部分可能会迭代到10级深度,而且我不喜欢这种模式的进行方式。

此数据集来自运行复杂CTE查询的存储过程,由于我们混合使用大量数据库,因此我不希望尝试使用Entity Framework进行此工作,因此我们需要更好地控制通过我们正在编写的SQL(因此可以使用存储过程)。最终,它将最终以JSON形式出现,我将在浏览器中将其呈现为可折叠树。

这是我希望稍微清理一下的丑陋部分。在开始遍历各个级别之前,这里发生的事情的要旨是:

  1. 建立第一个项目(不完整,但这是主要项目)。
  2. 执行存储过程(带有参数)以返回数据表。
  3. 创建要嵌套的对象的扁平列表。
  4. 获取BOM表中存在的嵌套级别的总数。
  5. 以非常难看的方式遍历各个级别。
public BOMItemModel GetItemBOM(string item)
        {
            try
            {
                var bom = new BOMItemModel { PLPartNumber = item, BOMLevel = 0 };
                var par = new Hashtable();
                par.Add("@Item", item);
                var dt = db.GetDataTable("[part].[getItemBOM]", par);
                var bomList = new List<BOMItemModel>();
                foreach(DataRow r in dt.Rows)
                {
                    bomList.Add(MapBomItem(r));
                }
                var bomLevels = bomList.Max(x => x.BOMLevel);
                for(var i = 1; i < bomLevels; i++)
                {
                    foreach (var b in bomList.Where(x => x.BOMLevel == i).ToList())
                    {
                        if (i == 1)
                        {
                            bom.SubItems.Add(b);
                        }
                        else
                        {
                            if (i == 2)
                            {
                                var lvl2Items = bom.SubItems;
                                var parent1 = lvl2Items.FirstOrDefault(x => x.PLPartNumber == b.ParentPLNumber);
                                if (parent1 != null) parent1.SubItems.Add(b);
                            }
                            if (i == 3)
                            {
                                var lvl2Items = bom.SubItems;
                                foreach(var lvl2 in lvl2Items)
                                {
                                    var lvl3Items = lvl2.SubItems;
                                    var parent2 = lvl3Items.FirstOrDefault(x => x.PLPartNumber == b.ParentPLNumber);
                                    if (parent2 != null) parent2.SubItems.Add(b);
                                }
                            }
                            if (i == 4)
                            {
                                var lvl2Items = bom.SubItems;
                                foreach (var lvl2 in lvl2Items)
                                {
                                    var lvl3Items = lvl2.SubItems;
                                    foreach (var lvl3 in lvl3Items)
                                    {
                                        var lvl4Items = lvl3.SubItems;
                                        var parent3 = lvl4Items.FirstOrDefault(x => x.PLPartNumber == b.ParentPLNumber);
                                        if (parent3 != null) parent3.SubItems.Add(b);
                                    }
                                }
                            }
                            if (i == 5)
                            {
                                var lvl2Items = bom.SubItems;
                                foreach (var lvl2 in lvl2Items)
                                {
                                    var lvl3Items = lvl2.SubItems;
                                    foreach (var lvl3 in lvl3Items)
                                    {
                                        var lvl4Items = lvl3.SubItems;
                                        foreach (var lvl4 in lvl4Items)
                                        {
                                            var lvl5Items = lvl4.SubItems;
                                            var parent4 = lvl5Items.FirstOrDefault(x => x.PLPartNumber == b.ParentPLNumber);
                                            if (parent4 != null) parent4.SubItems.Add(b);
                                        }
                                    }
                                }
                            }
                            if (i == 6)
                            {
                                var lvl2Items = bom.SubItems;
                                foreach (var lvl2 in lvl2Items)
                                {
                                    var lvl3Items = lvl2.SubItems;
                                    foreach (var lvl3 in lvl3Items)
                                    {
                                        var lvl4Items = lvl3.SubItems;
                                        foreach (var lvl4 in lvl4Items)
                                        {
                                            var lvl5Items = lvl4.SubItems;
                                            foreach (var lvl5 in lvl5Items)
                                            {
                                                var lvl6Items = lvl5.SubItems;
                                                var parent5 = lvl6Items.FirstOrDefault(x => x.PLPartNumber == b.ParentPLNumber);
                                                if (parent5 != null) parent5.SubItems.Add(b);
                                            }
                                        }
                                    }
                                }
                            }
                        }

                    }
                }

                return bom;
            }
            catch (Exception ex)
            {
                Log.Error(ex.Message, ex);
            }
            return null;
        }

这是我的模型或类的样子:

public class BOMItemModel
{
    public BOMItemModel()
    {
        SubItems = new List<BOMItemModel>();
    }
   public string ParentPLNumber { get; set; }
   public string PartNumber { get; set; }
   public string PartListName { get; set; }
   public string ItemNumber { get; set; }
   public string PLPartNumber { get; set; }
   public string PartType { get; set; }
   public string PLManufacturer { get; set; }
   public string PLDescription { get; set; }
   public decimal Qty { get; set; }
   public int BOMLevel { get; set; }
   public List<BOMItemModel> SubItems { get; set; }
}

该类的最后一个属性是我要填充父项的子项的位置,这可以嵌套多个层次。

1 个答案:

答案 0 :(得分:0)

是的,以下内容会更好:

window.moment = moment;

此外,当找不到父对象时,我会抛出错误。有关更通用的方法,请参见我的另一个示例:Converting table in tree