Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在linq中创建一个树结构,其中有一个列表源,其父-子作为对象的字符串_C#_Linq_Razor_2sxc - Fatal编程技术网

C# 在linq中创建一个树结构,其中有一个列表源,其父-子作为对象的字符串

C# 在linq中创建一个树结构,其中有一个列表源,其父-子作为对象的字符串,c#,linq,razor,2sxc,C#,Linq,Razor,2sxc,我首先列出一个包含以下数据的列表: Name______________ Parent__________Description_______________FilesCoded________CodingReferences "Blue"____________ "1.Colors"______"whatever"________________10________________11 "Red"_______

我首先列出一个包含以下数据的列表:

Name______________ Parent__________Description_______________FilesCoded________CodingReferences

"Blue"____________ "1.Colors"______"whatever"________________10________________11

"Red"_____________ "1.Colors"______"this"____________________2_________________3

"LightBlue"_______ "Blue"__________"that"____________________3_________________4

"Square"__________ "3.Forms"_______""________________________3_________________6

"ClearBlue"_______ "LightBlue"_____""________________________0_________________0
我需要创建以下输出:

1.Colors

____Blue

________LightBlue

____________ClearBlue

3.Forms

____Square
我使用了这段代码,这很有技巧,但是我在树上有大约15到20个级别,这使得代码很难看而且效率很低。有没有办法做到这一点:

  • 更简单,函数在各个级别循环,而不是每次复制代码
  • 更快。该表相当大,因此每增加一级,速度都会变慢
  • 当前代码:

    @{
        var Cats = AsList(App.Data["Categories"]).OrderBy(o => o.Parent).ThenBy(oo => oo.Name);
        // List of objects with: Name, Parent, Description, and other fields.
        var FirstLevelTree = Cats.Where(a => Char.IsNumber(a.Name[0])).Select(s => s.Name).Distinct();
    }
    
    @functions{
        public CategoryInfo setCatInfo (string catName)
        {
            var Cats = AsList(App.Data["Categories"]);
            
            var returnInfo = new CategoryInfo();
            returnInfo.desc = "Error: empty string";
            returnInfo.info = "Error: empty string";
            
            var checkCat = Cats.Where(n => n.Name == catName);
            if (checkCat.Count() != 1)
            {
                returnInfo.info = "Error: no such cat in list";
                returnInfo.desc = "Error: no such cat in list";
            } else {
                var thisCat = checkCat.First();
                returnInfo.info = thisCat.Name + "somethingelse";
                returnInfo.desc = thisCat.Description + "alsosomethingelse";
            }
            return returnInfo;
        }
        
        public class CategoryInfo {
            public string info {get;set;}
            public string desc {get;set;}
        }
    }
    
    <div id="myCats">
    
        @foreach(var top in FirstLevelTree)
        {
            <p>@top</p>
            var setlvlOne = Cats.Where(a => a.Parent == top);
            foreach(var lvlOne in setlvlOne)
            {
                var getLvlOneInfo = setCatInfo(lvlOne.Name);
                <p style="margin-left: 20px;">@Html.Raw(getLvlOneInfo.info)</p>
                   if (!String.IsNullOrEmpty(getLvlOneInfo.desc))
                   {
                        <p style="margin-left: 30px;">@Html.Raw(getLvlOneInfo.desc)</p>
                   }
                var setlvlTwo = Cats.Where(b => b.Parent == lvlOne.Name);
                foreach(var lvlTwo in setlvlTwo)
                {
                    var getLvlTwoInfo = setCatInfo(lvlTwo.Name);
                    <p style="margin-left: 40px;">@Html.Raw(getLvlTwoInfo.info)</p>
                       if (!String.IsNullOrEmpty(getLvlTwoInfo.desc))
                       {
                            <p style="margin-left: 50px;">@Html.Raw(getLvlTwoInfo.desc)</p>
                       }
                    var setlvlThree = Cats.Where(c => c.Parent == lvlTwo.Name);
                    foreach(var lvlThree in setlvlThree)
                    {
                        var getLvlThreeInfo = setCatInfo(lvlThree.Name);
                        <p style="margin-left: 60px;">@Html.Raw(getLvlThreeInfo.info)</p>
                           if (!String.IsNullOrEmpty(getLvlThreeInfo.desc))
                           {
                                <p style="margin-left: 70px;">@Html.Raw(getLvlThreeInfo.desc)</p>
                           }
                        var setlvlFour = Cats.Where(d => d.Parent == lvlThree.Name);
                        foreach(var lvlFour in setlvlFour)
                        {
                            var getLvlFourInfo = setCatInfo(lvlFour.Name);
                             <p style="margin-left: 80px;">@Html.Raw(getLvlFourInfo.info)</p>
                               if (!String.IsNullOrEmpty(getLvlFourInfo.desc))
                               {
                                    <p style="margin-left: 90px;">@Html.Raw(getLvlFourInfo.desc)</p>
                               }
                            var setlvlFive = Cats.Where(e => e.Parent == lvlFour.Name);
                            foreach(var lvlFive in setlvlFive)
                            {
                                var getLvlFiveInfo = setCatInfo(lvlFive.Name);
                                <p style="margin-left: 100px;">@Html.Raw(getLvlFiveInfo.info)</p>
                                   if (!String.IsNullOrEmpty(getLvlFiveInfo.desc))
                                   {
                                        <p style="margin-left: 110px;">@Html.Raw(getLvlFiveInfo.desc)</p>
                                   }
                            }
                        }
                    }
                }
            }  
        }
    </div>
    
    @{
    var Cats=AsList(App.Data[“Categories”]).OrderBy(o=>o.Parent)。ThenBy(oo=>oo.Name);
    //具有以下字段的对象列表:名称、父项、说明和其他字段。
    var FirstLevelTree=Cats.Where(a=>Char.IsNumber(a.Name[0])).Select(s=>s.Name.Distinct();
    }
    @功能{
    公共类别信息setCatInfo(字符串catName)
    {
    var Cats=AsList(应用程序数据[“类别]);
    var returnInfo=new CategoryInfo();
    returnInfo.desc=“错误:空字符串”;
    returnInfo.info=“错误:空字符串”;
    var checkCat=Cats.Where(n=>n.Name==catName);
    如果(检查cat.Count()!=1)
    {
    returnInfo.info=“错误:列表中没有此类cat”;
    returnInfo.desc=“错误:列表中没有此类cat”;
    }否则{
    var thisCat=checkCat.First();
    returnInfo.info=thisCat.Name+“somethingelse”;
    returnInfo.desc=thisCat.Description+“alsosomethingelse”;
    }
    返回返回信息;
    }
    公共类类别信息{
    公共字符串信息{get;set;}
    公共字符串desc{get;set;}
    }
    }
    @foreach(FirstLevelTree中的变量top)
    {
    @顶

    var setlvlOne=Cats.Where(a=>a.Parent==top); foreach(setlvlOne中的变量lvlOne) { var getLvlOneInfo=setCatInfo(lvlOne.Name);

    @Html.Raw(getLvlOneInfo.info)

    如果(!String.IsNullOrEmpty(getLvlOneInfo.desc)) {

    @Html.Raw(getLvlOneInfo.desc)

    } var setlvlTwo=Cats.Where(b=>b.Parent==lvlOne.Name); foreach(setlvlTwo中的var lvlTwo) { var getLvlTwoInfo=setCatInfo(lvlTwo.Name);

    @Html.Raw(getLvlTwoInfo.info)

    如果(!String.IsNullOrEmpty(getLvlTwoInfo.desc)) {

    @Html.Raw(getLvlTwoInfo.desc)

    } var setlvltree=Cats.Where(c=>c.Parent==lvlTwo.Name); foreach(setlvltree中的var lvltree) { var getLvlThreeInfo=setCatInfo(lvlThree.Name);

    @Html.Raw(getLvlThreeInfo.info)

    如果(!String.IsNullOrEmpty(getLvlThreeInfo.desc)) {

    @Html.Raw(getLvlThreeInfo.desc)

    } var setlvlFour=Cats.Where(d=>d.Parent==lvltree.Name); foreach(在setlvlFour中的var lvlFour) { var getLvlFourInfo=setCatInfo(lvlFour.Name);

    @Html.Raw(getLvlFourInfo.info)

    如果(!String.IsNullOrEmpty(getLvlFourInfo.desc)) {

    @Html.Raw(getLvlFourInfo.desc)

    } var setlvlFive=Cats.Where(e=>e.Parent==lvlFour.Name); foreach(setlvlFive中的var lvlFive) { var getLvlFiveInfo=setCatInfo(lvlFive.Name);

    @Html.Raw(getLvlFiveInfo.info)

    如果(!String.IsNullOrEmpty(getLvlFiveInfo.desc)) {

    @Html.Raw(getLvlFiveInfo.desc)

    } } } } } } }
    简单的

    对。创建一个递归调用自身的。这将允许您避免示例中的所有重复代码,并且它将支持基本上无限的最大深度,而不需要任何更多的代码更改

    更快

    这取决于你一直在做什么

    随着级别的增加,您可能只是生成了更多的HTML。这将在服务器端花费更多的时间,同时也会使浏览器陷入困境。为了避免这种问题,您可能只需要查看加载用户实际感兴趣的部分。例如,您可以创建一个折叠结构,当用户向下钻取数据时,该结构只能从更深的节点加载数据

    我还将密切关注您未提供的代码中可能发生的情况

    • setCatInfo
      是一项昂贵的操作吗
    • 什么是支持猫的集合?如果它使用延迟执行,比如实体框架DbSet,那么每次迭代
      Cats.Where(…)
      调用的结果时,您可能会执行单独的往返
    无论哪种方式,到处执行
    Cats.Where()
    都会给页面生成带来
    O(n²)
    算法复杂性。我建议将所有类别收集到一个查找中,按其父类别分组:

    var catsByParent = Cats.ToLookup(c => c.Parent);
    
    这是一个一次性的
    O(logn)
    操作,从那以后,您应该能够更快地获得具有给定父级的类别

    var thisLevel = catsByParent[parentLevel.Name];
    
    旁注
    • 使用
      @Html.Raw()。莫斯
      
      @inherits ToSic.Sxc.Dnn.RazorComponent
      
      @{
          var Cats = AsList(App.Data["Categories"]).OrderBy(o => o.Parent).ThenBy(oo => oo.Name);
          // List of objects with: Parent, Name, Description, FilesCoded, CodingReferences
          var CatsGrouped = Cats.ToLookup(a => a.Parent);
          var FirstLevelTree = Cats.Where(a => Char.IsNumber(a.Name[0])).Select(s => s.Name).Distinct();
      }
      
      <style>
      .setmargins{
          padding-left: 2em;
      }
      </style>
      
      @helper getChildren(string CatName, dynamic CatsGrouped)
      {    
          var setChilds = CatsGrouped[CatName];
          <div class="setmargins">
          @foreach(var child in setChilds)
          {
              <div class="toogle">
                  @child.Name (a: @child.FilesCoded urs: @child.CodingReferences)
                  <div class="toogletarget setmargins">@(new HtmlString(child.Description))</div>
              </div>
              @getChildren(child.Name, CatsGrouped)
          }
          </div>
      }
      
      <div id="myCats" @Edit.TagToolbar(Content)>
          @foreach(var top in FirstLevelTree)
          {
              <div>@top</div>
              @getChildren(top, CatsGrouped)
          }
      </div>
      
      <script>
          $( ".toogletarget" ).toggle();
          $( ".toogle" ).click(function() {
              $(this).find('.toogletarget').toggle();
          });
      </script>