我有一些来自数据库的平面数据,如下所示:
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
}
}
}
};
最终将在树视图中显示如下:
+ Admin(Group)
John Doe(用户)
简史密斯(用户)
+支持(组)
约翰尼支持(用户)
+ SubSupport(Group)
Sub Johnny支持(用户)
+生产(集团)
约翰尼制作(用户)
到目前为止,我已经提出将平面数据转换为上述模型:
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; }
}
答案 0 :(得分:1)
我在3次通过中做到了这一点:
创建所有Group
类,并使用除子组之外的数据填充它们,将它们逐步添加到字典映射ID到组。
遍历字典中的所有组并将子项添加到其父项中。 Groups
孩子名单。
返回没有父组的所有组的筛选列表 - 这些是根组。 (我还按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);
}
}