平面数据以层次模型C#(Flat Data to Hierarchical Model C#)

2019-10-21 06:57发布

我有一些平面数据来自看起来像这样的数据库来:

List<FlatDataGroup> elements = new List<FlatDataGroup>()
        {
            new FlatDataGroup {Text = "", GroupID = 1, ParentGroupID = 0, GroupName = "Admin", UserID = 1, UserName = "John Doe"},
            new FlatDataGroup {Text = "", GroupID = 1, ParentGroupID = 0, GroupName = "Admin", UserID = 2, UserName = "Jane Smith"},
            new FlatDataGroup {Text = "", GroupID = 2, ParentGroupID = 1, GroupName = "Support", UserID = 3, UserName = "Johnny Support"},
            new FlatDataGroup {Text = "", GroupID = 3, ParentGroupID = 2, GroupName = "SubSupport", UserID = 4, UserName = "Sub Johnny Support"},
            new FlatDataGroup {Text = "", GroupID = 4, ParentGroupID = 1, GroupName = "Production", UserID = 5, UserName = "Johnny Production"}
        };

我想将其转换为这样的:

List<Group> model = new List<Group>
            {
                new Group()
                {
                    ID = 1,
                    Name = "Admin",
                    ParentGroupID = 0,
                    Type = "Group",
                    Users = new List<User>()
                    {
                        new User()
                        {
                            ID = 1,
                            Name = "John Doe",
                            GroupID = 1,
                            Type = "User",
                        },
                        new User()
                        {
                            ID = 2,
                            Name = "Jane Smith",
                            GroupID = 1,
                            Type = "User",
                        },
                    },
                    Groups = new List<Group>
                    {
                        new Group()
                        {
                            ID = 2,
                            Name = "Support",
                            ParentGroupID = 1,
                            Type = "Group",
                            Users = new List<User>()
                            {
                                new User()
                                {
                                    ID = 3,
                                    Name = "Johnny Support",
                                    GroupID = 2,
                                    Type = "User",
                                }
                            },
                            Groups = new List<Group>()
                            {
                                new Group()
                                {
                                    ID = 3,
                                    Name = "SubSupport",
                                    ParentGroupID = 2,
                                    Type = "Group",
                                    Users = new List<User>()
                                    {
                                        new User()
                                        {
                                            ID = 4,
                                            Name = "Sub Johnny Support",
                                            GroupID = 3,
                                            Type = "User",
                                        }
                                    },
                                    Groups = null
                                }
                            }
                        },
                        new Group()
                        {
                            ID = 4,
                            Name = "Production",
                            ParentGroupID = 1,
                            Type = "Group",
                            Users = new List<User>()
                            {
                                new User()
                                {
                                    ID = 5,
                                    Name = "Johnny Production",
                                    GroupID = 4,
                                    Type = "User",
                                }
                            },
                            Groups = null
                        }
                    }
                }
            };

这在树视图最终将显示如下:

+管理(集团)
李四(用户)
简·史密斯(用户)
+支持(集团)
约翰尼支持(用户)
+ SubSupport(集团)
子约翰尼支持(用户)
+生产(集团)
约翰尼生产(用户)

这是我想出这么远的平面数据转换成上述模型:

List<Group> model = new List<Group>();

        var parentGrouping = elements.GroupBy(x => x.ParentGroupID);

        foreach (var parentGroup in parentGrouping)
        {
            var grouping = parentGroup.GroupBy(y => y.GroupID);

            foreach (var group in grouping)
            {
                Group groupItem = new Group()
                {
                    ID = group.FirstOrDefault().GroupID,
                    Name = group.FirstOrDefault().GroupName,
                    ParentGroupID = group.FirstOrDefault().ParentGroupID,
                    Type = "Group",
                    Users = new List<User>()
                };

                foreach (var user in group)
                {
                    groupItem.Users.Add(new User()
                        {
                            ID = user.UserID,
                            Name = user.UserName,
                            GroupID = user.GroupID,
                            Type = "User",
                        });
                }

                model.Add(groupItem);
            }
        }

我所有的群体推出了自己的孩子用户一起,但不保留层次。 我想我可能需要递归地做到这一点,但我似乎无法让我的头周围。 任何帮助将不胜感激。

下面是完整起见型号:

public class FlatDataGroup
{
    public string Text { get; set; }
    public int GroupID { get; set; }
    public int ParentGroupID { get; set; }
    public string GroupName { get; set; }
    public int UserID { get; set; }
    public string UserName { get; set; }
}

public class Group
{
    public int ID { get; set; }
    public int ParentGroupID { get; set; }
    public string Name { get; set; }
    public List<Group> Groups { get; set; }
    public List<User> Users { get; set; }
    public string Type { get; set; }
}

public class User
{
    public int ID { get; set; }
    public int GroupID { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
 }

Answer 1:

我做这3关:

  1. 创建所有Group类和比子组其他数据填充它们,将它们添加到递增的字典映射ID到组。

  2. 通过字典中的所有组回路,并添加孩子父母的Groups孩子的名单。

  3. 返回无父组各组的过滤列表 - 这是根组。 (我也整理他们的ID删除随机排序,该词典将介绍)。

从而:

public static class FlatDataGroupExtensions
{
    public const string UserType = "User";
    public const string GroupType = "Group";

    public static List<Group> ToGroups(this IEnumerable<FlatDataGroup> elements)
    {
        // Allocate all groups and index by ID.
        var groups = new Dictionary<int, Group>();
        foreach (var element in elements)
        {
            Group group;
            if (!groups.TryGetValue(element.GroupID, out group))
                groups[element.GroupID] = (group = new Group() { ID = element.GroupID, Name = element.GroupName, ParentGroupID = element.ParentGroupID, Type = GroupType });
            group.Users.Add(new User() { GroupID = element.GroupID, ID = element.UserID, Name = element.UserName, Type = UserType });
        }
        // Attach child groups to their parents.
        foreach (var group in groups.Values)
        {
            Group parent;
            if (groups.TryGetValue(group.ParentGroupID, out parent) && parent != group) // Second check for safety.
                parent.Groups.Add(group);
        }
        // Return only root groups, sorted by ID.
        return groups.Values.Where(g => !groups.ContainsKey(g.ParentGroupID)).OrderBy(g => g.ID).ToList();
    }
}

我还修改了你的Group类一点点自动分配名单:

public class Group
{
    List<Group> groups = new List<Group>();
    List<User> users = new List<User>();

    public int ID { get; set; }
    public int ParentGroupID { get; set; }
    public string Name { get; set; }
    public string Type { get; set; }
    public List<Group> Groups { get { return groups; } }
    public List<User> Users { get { return users; } }

    public override string ToString()
    {
        return string.Format("Group: ID={0}, Name={1}, Parent ID={2}, #Users={3}, #Groups={4}", ID, Name, ParentGroupID, Users.Count, Groups.Count);
    }
}


文章来源: Flat Data to Hierarchical Model C#