我有以下型号的列表:
public record Project(
int Id,
int AuthorId,
int TeamId,
string Name,
string Description,
DateTime CreatedAt,
DateTime Deadline)
public record Task(
int Id,
int ProjectId,
int PerformerId,
string Name,
string Description,
TaskState State,
DateTime CreatedAt,
DateTime? FinishedAt)
public record User(
int Id,
int? TeamId,
string FirstName,
string LastName,
string Email,
DateTime RegisteredAt,
DateTime BirthDay)
字符串
要编写Linq的任务,该任务按用户ID检索UserInfoDto。UserInfoDto具有以下结构:UserDto User - user ProjectDto LastProject -用户的最后一个项目(基于创建日期)。如果用户没有项目,则应为空。int LastProjectTasksCount -最后一个项目下的任务总数。如果用户没有项目或项目没有任务,则应为0。int NotFinishedOrCanceledTasksCount -用户未完成或已取消任务的总数(状态= ToDo或InProgress或Canceled)。如果用户没有任务,则应为0。(用户的任务不是项目的任务)TaskDto LongestTask -用户的最长任务(按持续时间计)(结束日期-创建日期)。确保考虑任务尚未完成的情况。(用户的任务而不是项目的任务)
我有什么:
public async Task<UserInfoDto> GetUserInfoAsync(int userId)
{
var tasks = await _dataProvider.GetTasksAsync();
var users = await _dataProvider.GetUsersAsync();
var projects = await _dataProvider.GetProjectsAsync();
return users.Join(tasks,
user => user.Id,
task => task.PerformerId,
(user, task) => new
{
User = user,
UserTask = task,
}).Join(projects,
firstJoin => firstJoin.User.Id,
project => project.AuthorId,
(firstJoin, userProject) => new
{
User = firstJoin.User,
UserTask = firstJoin.UserTask,
UserProject = userProject,
}).Join(tasks,
secondJoin => secondJoin.UserProject.Id,
task => task.ProjectId,
(secondJoin, task) => new
{
User = secondJoin.User,
UserTask = secondJoin.UserTask,
UserProject = secondJoin.UserProject,
ProjectTask = task,
})
.Where(r=>r.User.Id == userId)
.GroupBy(r=>r.User)
.Select(g=>
{
var lastUserProject = g.Select(r=>r.UserProject)
.MaxBy(p=>p.CreatedAt);
var lastProjectTaskCount = g.Select(r=>r.ProjectTask).Distinct()
.Count(p=>p.ProjectId == lastUserProject.Id);
var notFinishedOrCanceledTasksCount = g.Select(r=>r.UserTask).Distinct()
.Count(t=>t.State == TaskState.ToDo
|| t.State == TaskState.InProgress
|| t.State == TaskState.Canceled);
var longestTask = g.Select(r=>r.UserTask)
.Where(t=>t.FinishedAt is not null)
.MaxBy(t=> t.FinishedAt - t.CreatedAt);
var user = g.Key;
return _mapper
.Map<UserInfoDto>((user,
lastUserProject,
lastProjectTaskCount,
longestTask,
notFinishedOrCanceledTasksCount));
}).FirstOrDefault();
}
型
1条答案
按热度按时间dphi5xsq1#
答案的关键是看用户、任务和项目之间的关系。Task是具有指向User和Project的外键的对象。但不是每个用户都有任务,也不是每个项目都有任务。因此,首先将User左外连接到Task,然后将其左外连接到Project,即两个左连接。在Linq中,左连接是通过GroupJoin/SelectMany/DefaultIfEmpty实现的。完成后,按用户分组,最后聚合与每个用户关联的所有相关任务/项目。
下面的代码返回:
个字符