.Net Core API & 具有多对多关系映射的 Automapper
.Net Core API & Automapper with many to many relationship mapping
实体 User-UsersProjects-Project 之间存在多对多关系。
我想要获取分配给指定(按 projectID)项目的用户的映射列表,其中包含有关通常分配给用户的项目数量的信息,而不是每个项目。
请看我的代码
控制器
[HttpGet("{projectId}/users-assigned")]
[Description("Get list of users assigned to a specified project.")]
public async Task<ActionResult> GetProjectUsers(int projectId)
{
if (!ProjectExistById(projectId)) return NotFound("Project doesn't exist");
var project = await _context.Projects.Include(x => x.UserProjects).ThenInclude(z => z.User).SingleOrDefaultAsync(x => x.ProjectId == projectId);
var users = project.UserProjects.Select(x => x.User).ToList();
var usersDto = _mapper.Map<ICollection<UserForProjectDTO>>(users);
return Ok(usersDto);
}
实体
public class AppUser : IdentityUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<AppUserProject> UserProjects { get; set; }
}
public class Project
{
[Key]
public int ProjectId { get; set; }
public string Number { get; set; }
public string Name { get; set; }
public ICollection<AppUserProject> UserProjects { get; set; }
}
public class AppUserProject
{
[Key]
public int UserId { get; set; }
public AppUser User { get; set; }
[Key]
public int ProjectId { get; set; }
public Project Project { get; set; }
}
DTO
public class UserForProjectDTO
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int ProjectsCount { get; set; }
}
AutoMapper 配置文件
CreateMap<AppUser, UserForProjectDTO>();
CreateMap<AppUserProject, UserForProjectDTO>();
当前结果/api/Projects/11/users-assigned
[
{
"id": 4,
"firstName": "Robert",
"lastName": "Lewandowski",
"projectsCount": 0
},
{
"id": 6,
"firstName": "Ernest",
"lastName": "Giovannni",
"projectsCount": 0
},
{
"id": 7,
"firstName": "Mark",
"lastName": "Looser",
"projectsCount": 0
},
{
"id": 8,
"firstName": "Frank",
"lastName": "Lampard",
"projectsCount": 0
},
{
"id": 9,
"firstName": "Mark",
"lastName": "Ruffalo",
"projectsCount": 0
}
]
预期结果
[
{
"id": 4,
"firstName": "Robert",
"lastName": "Lewandowski",
"projectsCount": 4
},
{
"id": 6,
"firstName": "Ernest",
"lastName": "Giovannni",
"projectsCount": 2
},
{
"id": 7,
"firstName": "Mark",
"lastName": "Looser",
"projectsCount": 2
},
{
"id": 8,
"firstName": "Frank",
"lastName": "Lampard",
"projectsCount": 1
},
{
"id": 9,
"firstName": "Mark",
"lastName": "Ruffalo",
"projectsCount": 1
}
]
我的数据库
现在我总是得到 0 或 1(取决于我如何映射,但它仍然不是我所期望的)。
问题是因为我想通过项目 ID 获取具有项目数量的用户列表,而不是针对所有项目。这是我第一次遇到这种问题。任何提示都会有用。
我认为您在这里不需要 AutoMapper。一次性查询,无需第三方库,可自行投影所需属性
var users =
from p in context.Projects
where p.ProjectId == projectId
from up in p.UserProjects
select new UserForProjectDTO
{
Id = up.UserId,
FirstName = up.User.FirstName,
LastName = up.User.LastName,
ProjectsCount = up.User.UserProjects.Count()
};
作为一个好处,您可以更快地查询,只加载需要的字段而不会产生开销。
实体 User-UsersProjects-Project 之间存在多对多关系。
我想要获取分配给指定(按 projectID)项目的用户的映射列表,其中包含有关通常分配给用户的项目数量的信息,而不是每个项目。
请看我的代码
控制器
[HttpGet("{projectId}/users-assigned")]
[Description("Get list of users assigned to a specified project.")]
public async Task<ActionResult> GetProjectUsers(int projectId)
{
if (!ProjectExistById(projectId)) return NotFound("Project doesn't exist");
var project = await _context.Projects.Include(x => x.UserProjects).ThenInclude(z => z.User).SingleOrDefaultAsync(x => x.ProjectId == projectId);
var users = project.UserProjects.Select(x => x.User).ToList();
var usersDto = _mapper.Map<ICollection<UserForProjectDTO>>(users);
return Ok(usersDto);
}
实体
public class AppUser : IdentityUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<AppUserProject> UserProjects { get; set; }
}
public class Project
{
[Key]
public int ProjectId { get; set; }
public string Number { get; set; }
public string Name { get; set; }
public ICollection<AppUserProject> UserProjects { get; set; }
}
public class AppUserProject
{
[Key]
public int UserId { get; set; }
public AppUser User { get; set; }
[Key]
public int ProjectId { get; set; }
public Project Project { get; set; }
}
DTO
public class UserForProjectDTO
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int ProjectsCount { get; set; }
}
AutoMapper 配置文件
CreateMap<AppUser, UserForProjectDTO>();
CreateMap<AppUserProject, UserForProjectDTO>();
当前结果/api/Projects/11/users-assigned
[
{
"id": 4,
"firstName": "Robert",
"lastName": "Lewandowski",
"projectsCount": 0
},
{
"id": 6,
"firstName": "Ernest",
"lastName": "Giovannni",
"projectsCount": 0
},
{
"id": 7,
"firstName": "Mark",
"lastName": "Looser",
"projectsCount": 0
},
{
"id": 8,
"firstName": "Frank",
"lastName": "Lampard",
"projectsCount": 0
},
{
"id": 9,
"firstName": "Mark",
"lastName": "Ruffalo",
"projectsCount": 0
}
]
预期结果
[
{
"id": 4,
"firstName": "Robert",
"lastName": "Lewandowski",
"projectsCount": 4
},
{
"id": 6,
"firstName": "Ernest",
"lastName": "Giovannni",
"projectsCount": 2
},
{
"id": 7,
"firstName": "Mark",
"lastName": "Looser",
"projectsCount": 2
},
{
"id": 8,
"firstName": "Frank",
"lastName": "Lampard",
"projectsCount": 1
},
{
"id": 9,
"firstName": "Mark",
"lastName": "Ruffalo",
"projectsCount": 1
}
]
我的数据库
现在我总是得到 0 或 1(取决于我如何映射,但它仍然不是我所期望的)。
问题是因为我想通过项目 ID 获取具有项目数量的用户列表,而不是针对所有项目。这是我第一次遇到这种问题。任何提示都会有用。
我认为您在这里不需要 AutoMapper。一次性查询,无需第三方库,可自行投影所需属性
var users =
from p in context.Projects
where p.ProjectId == projectId
from up in p.UserProjects
select new UserForProjectDTO
{
Id = up.UserId,
FirstName = up.User.FirstName,
LastName = up.User.LastName,
ProjectsCount = up.User.UserProjects.Count()
};
作为一个好处,您可以更快地查询,只加载需要的字段而不会产生开销。