平面数据分层模型C# [英] Flat Data to Hierarchical Model C#

查看:126
本文介绍了平面数据分层模型C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  List< FlatDataGroup>< p> elements = new List ()
{
新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},
新FlatDataGroup {Text =,GroupID = 3,ParentGroupID = 2,GroupName = SubSupport,UserID = 4,UserName =Sub Johnny Support},
FlatDataGroup {Text =,GroupID = 4,ParentGroupID = 1,GroupName =Production,UserID = 5,UserName = Johnny Production}
};

我想将其转换为:

 列表与LT;组> 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,
},
新用户()
{
ID = 2,
Name =Jane Smith,
GroupID = 1,
Type =User,
},
},
Groups = new List< Group> ;
{
新集团()
{
ID = 2,
名称=支持,
ParentGroupID = 1,
类型= Group,
Users = new List< User>()
{
new User()
{
ID = 3,
Name = Johnny Support,
GroupID = 2,
Type =User,
}
},
Groups = new List< Group>()
{
新集团()
{
ID = 3,
Name =SubSupport,
ParentGroupID = 2,
Type =Group,
Users = new List< 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>()
{
新用户()
{
ID = 5,
名称=Johnny Production,
GroupID = 4,
Type =User ,
}
},
Groups = null
}
}
}
};

最终会在treeview中显示如下:
$ b $ (用户)

&Admins(Group)

     Jane Smith(User )

     + Support(Group)

         Johnny Support(User )

         + SubSupport(Group)

           Sub Johnny支持(用户)

     + Production(Group)

   ;       Johnny Production(用户)



到目前为止,将数据输入到上面的模型中:

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

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

foreach(parentGrouping中的var parentGroup)
{
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用户在组中)
{
groupItem.Users.Add(新用户()
{
ID = user.UserID,
Name = user.UserName,
GroupID = user.GroupID,
Type =User,
});
}

model.Add(groupItem);


我的所有群组都与他们的子女用户一起出现,但该层次不被保留。我想我可能需要递归地做这件事,但我似乎无法摆脱它的困扰。任何帮助将不胜感激。



以下是完整性模型:

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

public class Group
{
public int ID {get;组; }
public int ParentGroupID {get;组; }
public string Name {get;组; }
公共列表< Group>组{get;组; }
public List< User>用户{get;组; }
public string Type {get;组; }
}

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


解决方案

3遍:


  1. 创建所有群组类并填充它们以外的数据,将它们递增添加到将字段映射到组的字典中。

  2. 循环浏览字典中的所有组并将孩子添加到他们父母的小组小孩列表中。 返回所有小组的过滤列表没有父组 - 这些是根组。 (我也通过ID对它们进行了排序,以去除字典将要介绍的随机排序。)

因此: p>

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

public static List< Group> ToGroups(这个IEnumerable< FlatDataGroup>元素)
{
//通过ID分配所有组和索引。
var groups = new Dictionary< int,Group>();
foreach(元素中的var元素)
{
群组;
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});
}
//将子组添加到父母。
foreach(var group in groups.Values)
{
组父;
if(groups.TryGetValue(group.ParentGroupID,out parent)&& parent!= group)//第二次检查安全性。
parent.Groups.Add(group);
}
//仅返回按ID排序的根组。
return groups.Values.Where(g =>!groups.ContainsKey(g.ParentGroupID))。OrderBy(g => g.ID).ToList();


我也修改了你的有点自动分配列表:

  public class Group 
{
列表< Group> groups = new List< Group>();
列表<用户> users = new List< User>();

public int ID {get;组; }
public int ParentGroupID {get;组; }
public string Name {get;组; }
public string Type {get;组; }
公共列表< Group>组{获得{返回组; }}
public List< User>用户{获得{返回用户; }}
$ b $ 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);
}
}


I have some flat data coming from the database that looks like this:

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"}
        };

I would like to convert it to this:

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
                        }
                    }
                }
            };

which will ultimately display like this in a treeview:

+Admin (Group)
    John Doe (User)
    Jane Smith (User)
    +Support (Group)
        Johnny Support (User)
        +SubSupport (Group)
            Sub Johnny Support (User)
    +Production (Group)
        Johnny Production (User)

This is what I've come up with so far to transform the flat data into the model above:

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);
            }
        }

All my groups come out along with their children users but the hierarchy is not preserved. I think I may need to do this recursively but I can't seem to get my head around it. Any help would be greatly appreciated.

Here are the models for the sake of completeness:

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; }
 }

解决方案

I'd do this in 3 passes:

  1. Create all Group classes and populate them with data other than child groups, adding them incrementally to a dictionary mapping ID to Group.

  2. Loop through all the groups in the dictionary and add children to their parents' Groups list of children.

  3. Return a filtered list of all groups with no parent group -- these are the root groups. (I also sorted them by ID to remove the random ordering that the dictionary will introduce.)

Thus:

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();
    }
}

I also modified your Group class a little to automatically allocate the lists:

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);
    }
}

这篇关于平面数据分层模型C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆