Utilizando AutoMapper dentro de la consulta LINQ .NET Core/EF
Tengo clases modelo. User
y Course
. Entonces tengo una tercera clase modelo que sirve como una mesa de búsqueda llamada CoursesForUser
.
Estas clases parecen algo así:
public class User
{
public string Id { get; set; }
public string UserName { get; set; }
}
public class CoursesForUser
{
public string Id { get; set; }
public string CourseId { get; set; }
public string UserId { get; set; }
}
public class Course
{
public string Id { get; set; }
public string Name { get; set; }
public ICollection Users { get; set; }
}
En AutoMapper, tengo los siguientes mapas:
CreateMap();
CreateMap();
Tengo una consulta de repo que estoy escribiendo que debe devolver un Dto. Que Dto se llama UserInfoDto
y se ve así:
public class UserInfoDto
{
public string Id { get; set; }
public ICollection CourseList { get; set; }
}
La consulta parece así:
public async Task GetUserInfo(string userId)
{
var user = from u in _context.Users
where u.Id == userId
join ucourses in _context.CoursesForUser on u.Id equals ucourses.UserId
select new UserInfoDto
{
Id = u.Id,
CourseList = _mapper.Map>(ucourses)
};
return await user.FirstOrDefaultAsync();
}
Sin embargo, el código está rompiendo en esa línea:
CourseList = _mapper.Map
AutoMapper está lanzando un error así que estoy seguro de que mi sintaxis está equivocada, no sé dónde está mal. ¿Alguna ayuda?
Pregunta hecha hace 3 años, 4 meses, 26 días - Por syntaxsorcerer
2 Respuestas:
-
El problema en tu código está en la forma en que estás intentando realizar el mapeo con AutoMapper dentro de la consulta LINQ. La forma correcta de realizar esto es primero obtener los datos de la consulta de LINQ y luego mapearlos con AutoMapper. Aquí te dejo una solución para corregir tu código:
csharp public async Task
GetUserInfo(string userId) { var user = await (from u in _context.Users where u.Id == userId select new { Id = u.Id, CoursesForUser = _context.CoursesForUser.Where(c => c.UserId == userId) }).FirstOrDefaultAsync(); var userInfoDto = new UserInfoDto { Id = user.Id, CourseList = _mapper.Map >(user.CoursesForUser) }; return userInfoDto; } En este caso, primero seleccionamos los datos necesarios de la consulta LINQ dentro de un objeto anónimo y luego realizamos el mapeo con AutoMapper utilizando la lista de cursos obtenida. De esta forma, evitamos el error que estabas experimentando al intentar realizar el mapeo directamente dentro de la consulta LINQ.
Espero que esta solución te sea de ayuda. ¡Déjame saber si tienes alguna otra pregunta o duda!
Respondida el Dec 21, 2020 a las 16:48 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Tu código se está rompiendo en la línea
CourseList = _mapper.Map
porque estás intentando asignar una lista de objetosList<ListOfCoursesForUserDtos>
a una propiedad de tipoICollection<ListOfCoursesForUserDtos>
. AutoMapper no puede realizar esta conversión automáticamente.Para resolver este problema, puedes utilizar el método
ProjectTo
de AutoMapper, que te permite especificar el tipo de destino de la proyección. Aquí tienes cómo puedes hacerlo:CourseList = user.Select(u => _mapper.Map
(u.CoursesForUser)).ToList() El método
ProjectTo
utiliza el mapaCreateMap<CoursesForUser, ListOfCoursesForUserDto>
que has configurado en AutoMapper para convertir cada objetoCoursesForUser
en un objetoListOfCoursesForUserDto
. Luego, el resultado se convierte en una lista y se asigna a la propiedadCourseList
.Aquí tienes el código completo actualizado:
public async Task
GetUserInfo(string userId) { var user = from u in _context.Users where u.Id == userId join ucourses in _context.CoursesForUser on u.Id equals ucourses.UserId select new UserInfoDto { Id = u.Id, CourseList = user.Select(u => _mapper.Map (u.CoursesForUser)).ToList() }; return await user.FirstOrDefaultAsync(); } Respondida el Dec 21, 2020 a las 16:55 - por Gemini
Votos positivos: 0 | Votos negativos: 0