c# - 按使用 linq 完成项目的用户对结果进行分组
问题描述
我想通过使用多个联接在最后对结果进行分组。
共有三个列表User
、Item
和ItemCompleted
:
用户列表:
//users
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
//output
[{
"Id": 2154,
"Name": "Joanne"
}, {
"Id": 2207,
"Name": "Kylie"
}, {
"Id": 2159,
"Name": "Madeleine"
},{
"Id": 2160,
"Name": "Mat"
}]
物品清单
//items
public class Item
{
public string Item { get; set; }
public int Id { get; set; }
}
//output
[{
"Id": 1,
"Name": "Item 1"
}, {
"Id": 2,
"Name": "Item 2"
}, {
"Id": 3,
"Name": "Item 3"
},{
"Id": 291,
"Name": "Item 291"
},{
"Id": 288,
"Name": "Item 288"
},{
"Id": 290,
"Name": "Item 290"
}]
]
项目完成列表
//completedItems
public class ItemCompleted
{
public int UserId { get; set; }
public int ModuleId { get; set; }
public string Event { get;set; }
}
//output
[{
"UserId": 2154,
"ModuleId": 1,
"Event": "Lesson"
}, {
"UserId": 2154,
"ModuleId": 2,
"Event": "Interactive Content"
}, {
"UserId": 2207,
"ModuleId": 3,
"Event": "Interactive Content"
}, {
"UserId": 2159,
"ModuleId": 2,
"Event": "Interactive Content"
}, {
"UserId": 2207,
"ModuleId": 2,
"Event": "Interactive Content",
}, {
"UserId": 2159,
"ModuleId": 1,
"Event": "Lesson"
}, {
"UserId": 2207,
"ModuleId": 1,
"Event": "Lesson"
}]
应用了左连接,Item
并CompletedItems
列出了 CompletedItem 的列表:
var itemsResult = from item in items
join completed in completedItems on item.Id equals completed.ModuleId into cmpltItem
from ct in cmpltItem.DefaultIfEmpty()
select new CompletedItem()
{
ModuleId = item.Id,
ItemType = ct?.Event,
Item = item.Activity,
UserId = ct?.UserId
};
如果该项目未由任何用户完成:
[{
"ModuleId": 291,
"Item": "Item 291",
"ItemType": null,
"UserId": null
}, {
"ModuleId": 288,
"Item": "Item 288",
"ItemType": null,
"UserId": null
}, {
"ModuleId": 290,
"Item": "Item 290",
"ItemType": null,
"UserId": null
}]
现在我想对用户名完成的项目数进行分组:
var groupedUserbyItem = users
.Select(c => new UserCompletedItem
{
Name = c.Name,
UserId = c.Id,
CompletedItems = itemsResult.Where(x => x.UserId == c.Id)
.Select(t => new CompletedItem { }).ToList()
})
.ToList();
用户完成项
public class UserCompletedItem
{
public string Name { get; set; }
public int UserId { get; set; }
public IEnumerable<CompletedItem> CompletedItems { get; set; }
}
public class CompletedItem
{
public int? ModuleId { get; set; }
public string Item { get; set; }
public string ItemType { get; set; }
public int? UserId { get; set; }
}
但我被困在与用户的项目分组中。
期望的输出:如果用户完成了一项、两项或没有项。
[{
"UserId": 2154,
"Name": "Joanne",
"CompletedItems": [{
"id": 1,
"Item": "Item 1",
"ItemType": "Lesson"
},
{
"id": 2,
"Item": "Item 2",
"ItemType": "Interactive Content"
}
]
},
{
"UserId": 2160,
"Name": "Mat",
"CompletedItems": []
},
{
"UserId": 2159,
"Name": "Madeleine",
"CompletedItems": [{
"id": 2,
"Item": "Item 2",
"ItemType": "Interactive Content"
}, {
"id": 1,
"Item": "Item 1",
"Event": "Lesson"
}]
},
{
"UserId": 2207,
"Name": "Madeleine",
"CompletedItems": [{
"id": 3,
"Item": "Item 3",
"ItemType": "Interactive Content"
}, {
"id": 2,
"Item": "Item 2",
"ItemType": "Interactive Content"
}, {
"id": 1,
"Item": "Item 1",
"Event": "Lesson"
}]
}
]
解决方案
您可以使用两个查询,如以下代码:
1 - 获得完成的项目:
var query1 = (from itemCompleted in itemCompleteds
join item in items on itemCompleted.ModuleId equals item.Id
select new
{
UserId = itemCompleted.UserId,
ModuleId = item.Id,
Item = item.Name,
ItemType = itemCompleted.Event
})
.Distinct()
.ToList();
2 - 按用户分组完成的项目并构建UserCompletedItem
:
var finalResult = (from user in users
join itemCompleted in query1 on user.Id equals itemCompleted.UserId into leftResults
from leftedResult in leftResults.DefaultIfEmpty()
group leftedResult by new { user.Id, user.Name } into grp
select new UserCompletedItem
{
UserId = grp.Key.Id,
Name = grp.Key.Name,
CompletedItems = grp
.Where(x => x != null)
.Select(x => new CompletedItem
{
ModuleId = x.ModuleId,
Item = x.Item,
ItemType = x.ItemType
}).ToList()
}).ToList();
我希望你觉得这有帮助。
推荐阅读
- laravel - 使用通配符 * 查看作曲家在所有视图 laravel 5 中加载变量
- c# - 使用 C# 和 fluent 库动态构建 Mongo Query
- asp.net - AspNetRoles 表未显示自定义字段
- android-studio - 如何使用 ibm watson 助手在文本视图上显示图像?
- arrays - 从数组中选择一个键值对
- css - 如何使数字和字母底部均匀
- linux - 为什么在linux中将文件从目录1移动到目录2时出错?
- jquery - 如果用户选择选项标签然后单击按钮,如何隐藏/显示
- php - WSSE - XML SOAP 安全和密钥加密和存储 (EncryptedData/EncryptedKey)
- vba - 如何通过 Selenium 和 VBA 根据 html 单击文本作为 SRP Banner 的元素?