代码之家  ›  专栏  ›  技术社区  ›  Alan Wayne

为树节点使用外部组的lambda表达式

  •  1
  • Alan Wayne  · 技术社区  · 6 年前

    下面的LINQ代码正确地为顶级专业代码的子级提供记录组。如何使用lambda?

    最上面的查询从数据库中获取视图咨询记录,并按专业名称对其进行正确分组:

    // get the records from the database.
                view_consulting[] v = MyNetwork.Medical.Client.GetConsultingStaff();
    
                // All records will first be grouped by the speciality name. The specialityGroup will hold all the records for the specific speciality.
                var s = v.GroupBy(p => p.speciality_name)
                    .Select((IGrouping<string, view_consulting> specialityGroup) =>
                          new SpecialityNode(specialityGroup.Key, specialityGroup, new speciality { speciality_name = specialityGroup.Key }));
                var ss = s.ToList();
    

    然后,每个特殊代码都有一个构造函数,如下所示:

    // The specialityGroup holds all the records for the speciality.
            public SpecialityNode(string name, IGrouping<string, view_consulting> specialityGroup, speciality data) : base(name, null, null, data)
            {
                // Create a subgroup for each office under each SpecialityNode.           
                var offices = new List<OfficeNode>();
    
                var officeGroups = from t in specialityGroup
                                   group t by t.office_name;
    
                foreach (var officegroup in officeGroups)
                {
                    foreach (var _office in officegroup)
                    {
                        var _officenode = new OfficeNode(_office.office_name, this, this, officegroup, new office { city = _office.city, office_name = _office.office_name, phone = _office.phone, fax = _office.fax, state = _office.state, street = _office.street });
                        offices.Add(_officenode);
                    }
                }
                Children = offices.ToList<ITreeNode>();
            }
    

    这一切都符合我的需要。请注意,最后一个foreach()使用的是对specialinode构造函数中外部foreach()的引用。

    所有这些“foreach”都可以组合成一个lambda表达式吗?

    事先谢谢。

    如果有助于澄清,这里是officenode构造函数。注意:它使用这个办公室所属的小组在每个办公室生成顾问。

    class OfficeNode : TreeViewBase
        {
            private office data;
    
            public class MyDoctor
            {
                public string lastname { get; internal set; }
                public string firstname { get; internal set; }
                public string speciality { get; internal set; }
                public consultant data { get; internal set; }
    
                public string nodename
                {
                    get { return string.Format("{0}  {1}  {2}", lastname, firstname, speciality); }
                }
            }
    
            // The name for the office node is the office name. The office node parent and root are the same and is the speciality node.
            public OfficeNode(string officename, ITreeNode _parent, ITreeNode _root, IGrouping<string, view_consulting> officeGroup, office _data) : base(officename, _parent, _root, _data)
            {
                var _doctors = officeGroup.Where(q => !string.IsNullOrEmpty(q.lastname))
                     .GroupBy(q => new MyDoctor {
                         lastname = q.lastname,
                         firstname = q.firstname,
                         speciality = q.speciality_name,
                         data = new consultant { lastname = q.lastname, firstname = q.firstname }
                     })
                     .Select(doctorGroup => new DoctorNode(doctorGroup.Key.nodename, this, _root, doctorGroup, doctorGroup.Key.data));
    
                Children = _doctors.ToList<ITreeNode>();
    
                City = _data.city;
                Phone = _data.phone;
                Fax = _data.fax; 
              //  Order = order ?? throw new ArgumentNullException(nameof(order));
    

    }

    1 回复  |  直到 6 年前
        1
  •  1
  •   TyCobb    6 年前

    是的,您可以使用 SelectMany . 选择许多 允许您将多个集合展平为一个集合。因为它似乎是你的 officeGroups 是可枚举的, 选择许多 将返回所有项的单个可枚举项。

    var list = officeGroups.SelectMany(o => o)
                            .Select(o => new OfficeNode(constructorParam1,
                                                        constructorParam2,
                                                        etc.))
                            .ToList();
    

    不过,现在看起来还是很干净。一旦你把所有的参数都转储进去,然后 Office 初始化器,它将比您的前臂更难读取和跟踪。它也将更难调试。

    编辑: 因为我错过了仍然需要 officeGroup 我们可以稍微透视一下,先从组中构建集合,然后利用匿名对象。

    var list = officeGroups.Select(og => new 
                                         {
                                            Offices = og.Select(o => new OfficeNode(o.office_name,
                                                                                    this,
                                                                                    this,
                                                                                    og,
                                                                                    etc.))
                                         }
                            .SelectMany(x => x.Offices)
                            .ToList();