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 objetos List<ListOfCoursesForUserDtos> a una propiedad de tipo ICollection<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 mapa CreateMap<CoursesForUser, ListOfCoursesForUserDto> que has configurado en AutoMapper para convertir cada objeto CoursesForUser en un objeto ListOfCoursesForUserDto. Luego, el resultado se convierte en una lista y se asigna a la propiedad CourseList.

    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