c# - 我如何 linq 对象分组
问题描述
如何对这些对象进行分组?我可以通过 LINQ 获取并绑定它。但这没有用,因为我需要反向分组。像那样 :
主组 > 组列表 > 子组列表
也许我可以通过 LINQ 查询首先获取值来做到这一点。我不知道。
我是 LINQ 的初学者。我没有太多信息。预先感谢您的帮助。我像这样获取并绑定 mongodb 数据:
var subGroupCollection = Database.GetCollection<SubGroup>(typeof(SubGroup).Name);
var groupCollection = Database.GetCollection<Group>(typeof(Group).Name);
var mainGroupCollection = Database.GetCollection<MainGroup>(typeof(MainGroup).Name);
var query = from sg in subGroupCollection.AsQueryable()
join mg in mainGroupCollection on sg.MainGroupId equals mg.Id into mainGroups
join z in groupCollection on sg.GroupId equals z.Id into groups
select new SoccerOddType
{
Id = sg.Id,
IsActive = sg.IsActive,
GroupId = sg.GroupId,
Name = sg.Name,
LastUpdateDate = sg.LastUpdateDate,
CreatedDate = sg.CreatedDate,
Order = sg.Order,
Discount = sg.Discount,
DiscountType = sg.DiscountType,
MainGroupId = sg.MainGroupId,
MainGroup = mainGroups.First(),
Group = groups.First()
};
从 :
public class MainGroup
{
public string Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
public class Group
{
public string Id { get; set; }
public string MainGroupId { get; set; }
[BsonIgnore] public Group MainGroup { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
}
public class SubGroup
{
public string Id { get; set; }
public string Name { get; set; }
public string MainGroupId { get; set; }
public string GroupId { get; set; }
[BsonIgnore] public Group MainGroup { get; set; }
[BsonIgnore] public Group Group { get; set; }
public bool IsActive { get; set; }
public decimal Discount { get; set; }
public EnmDiscountType DiscountType { get; set; }
}
到 :
public class MainGroupViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public List<GroupViewModel> Groups { get; set; }
}
public class GroupViewModel
{
public string Id { get; set; }
public string MainGroupId { get; set; }
public string Name { get; set; }
public bool IsActive { get; set; }
public List<SubGroupViewModel> SubGroups { get; set; }
}
public class SubGroupViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public string MainGroupId { get; set; }
public string GroupId { get; set; }
public bool IsActive { get; set; }
public decimal Discount { get; set; }
public EnmDiscountType DiscountType { get; set; }
}
解决方案
如果您有一个一对多的关系,使用外键,并且您想要项目及其子项目,例如学校及其学生、客户及其订单、主组及其子组,那么您可以使用简单的 Select得到你的结果,或使用GroupJoin
选择
var result = mainGroupCollection.Select(mainGroup => new MainGroupViewModel
{
Id = mainGroup.Id,
Name = mainGroup.Name,
...
// Keep only the Groups of this MainGroup, using foreign key
Groups = groupCollection
.Where(group => group.MainGroupId == mainGroup.Id)
.Select(group => new GroupViewModel
{
Id = group.Id,
Name = group.Name,
...
// Keep only the subGroups of this Group, using foreign key
SubGroups = subGroupCollection
.Where(subGroup => subGroup.GroupId == group.Id)
.Select(subGroup => new SubGroupViewModel
{
Id = group.Id,
Name = group.Name,
...
})
.ToList(),
})
.ToList(),
});
虽然这种方法有效,但效率不高,因为对于 mainGroupCollection 中的每个元素,它必须枚举整个 GroupCollection,而对于每个元素,它必须枚举整个 SubGroupCollection。
如果您从数据库中查询,则取决于您使用的 DBMS,这不是一个大问题。但是,我会去 GroupJoin
团体加入
Enumerable.GroupJoin效率更高(或 IQueryable 等效项)。Enumerable 版本使用 Dictionary 来查看它是否已经找到具有此 Id 的项目,因此它不需要对每个集合进行多次枚举。
// GroupJoin the mainGroupCollection with the groupCollection:
var result = mainGroupCollection.GroupJoin(groupCollection,
mainGroup = mainGroup.Id, // from every mainGroup take the primary key
group => group.MainGroupId, // from every group take the foreign key
// ResultSelector: for every mainGroup and its groups make one MainGroupViewModel
(mainGroup, groupsOfThisMainGroup) => new MainGroupViewModel
{
Id = mainGroup.Id,
Name = mainGroup.Name,
...
// for the Groups: GroupJoin the groups of this main group with the subGroups
Groups = groupsOfThisMainGroup.GroupJoin(subGroupCollection,
groupOfThisMainGroup => groupOfThisMainGroup.Id,
subGroup => subGroup.GroupId,
// result selector
(group, subGroupsOfThisGroup) => new GroupViewModel
{
Id = group.Id,
Name = group.Name,
SubGroups = subGroupsOfThisGroup.Select(subGroup => new SubGroupViewModel
{
Id = subGroup.Id,
Name = subGroup.Name,
...
})
.ToList(),
})
.ToList(),
});
推荐阅读
- python - 如何使用 Python 的加密包签署 AMP 更新缓存请求?
- amazon-web-services - 使用 SQS 和 DLQ 时是否应该禁用 lambda 重试?
- git - 如何从 .repos 文件添加子模块
- mysql - 如何在 2 个 Select 语句之间使用逻辑运算符?
- r - 如何比较两个data.frames并根据条件返回行?
- node.js - 由于 async-await,我在 JWT 令牌验证中遇到了一些错误
- python - 如何加快将列值从熊猫数据帧传输到另一个数据帧
- git - 推送时的 Git 本地提交时间戳
- r - R:导入文件的整个文件夹
- python - 为什么 Python 循环不循环回到问题