La .NET CONF 2024 acaba de terminar. Descubre las NOVEDADES de .NET 9 junto a los CAMBIOS que trae C# 13.
Puedes ver el contenido de este vídeo junto con su curso en el modo vídeo (similar a Udemy) si pulsas aquí.

Consultas y manipulación de datos con Entity Framework Core

Si que es verdad que he creado gran parte de este curso obviando uno de los apartados más importantes de todos, lo que viene siendo cómo realizamos consultas, o manipulamos datos en Entity Framework.

Para entender este post, recomiendo haber seguido gran parte del curso, pero mínimo entender cómo funcionan DbContext y DbSet, así como el modelo de datos que vamos a utilizar.

Y personalmente pienso que es recomendable que entiendas o tengas conocimientos tanto del patrón repositorio como del patrón UnitOfWork.

 

 

Antes de empezar, decir que los ejemplos van a estar puramente en Entity framework pero para algunos de ellos el código contendrá parte de la Web API, así, se le da más contexto dentro de una aplicación real. 

 

 

1 - Realizar consultas con Entity Framework Core

La  acción principal o más común que vamos a realizar dentro de Entity Framework van a ser las consultas, por ahora nos vamos a centrar en consultas simples y para ello podemos utilizar LINQ. Para los que no lo conocéis LINQ es un lenguaje de consulta en C# y en el caso de Entity Framework, traduce la consulta LINQ a una consulta SQL. 

 

En nuestro caso particular, vamos a querer consultar un usuario por ID:

public async Task<User?> GetById(int id)
    => await _context.Users
        .FirstOrDefaultAsync(x => x.Id == id);

O en este otro caso estamos cogiendo a todos los usuarios que el nombre de la experiencia es “Government”; osea, si ha trabajado para el gobierno.

public async Task<List<User>> GovernmentUsers()
    => await _context.Users
        .Include(a => a.Wokringexperiences
            .Where(we => we.Name == "Government"))
        .ToListAsync();

Además cómo te estás dando cuenta, en este ejemplo estamos enlazando dos tablas diferentes a través del metodo Include.

  • Nota: hay que tener cuidado de hacer este tipo de includes con filtros y tal, ya que pueden causarnos grandes problemas de rendimiento, siempre verifica la consulta que se ejecuta y comprueba que es la mejor posible.

 

 

2 - Crear Registros en la base de datos con Entity Framework core

Lo que vamos a hacer aquí es un insert, y la forma de realizar esta acción es muy sencilla.

 

Tenemos que construir el objeto de la entidad en el código, y luego añadirlo al DbSet correspondiente. Una vez añadido, simplemente guardamos con SaveChanges.

public async Task<User> Insert(User user)
{
    EntityEntry<User> insertedUser = await _context.Users.AddAsync(user);
    await _context.SaveChangesAsync();
    return insertedUser.Entity;
}

Recuerda que si utilizas El patrón unidad de trabajo no guardas en el repositorio, si no a nivel unidad de trabajo. 



3 - Modificar registros de una base de datos con Entity Framework Core

Para modificar un registro, tenemos que leer uno existente, como hemos visto en el primer punto, modificarlo y guardarlo.

 

Para este ejemplo, voy a crear un servicio denominado UpdateUserEmail el cual utiliza unit of work (unidad de trabajo).

En este servicio tenemos un único método que recibe el id del usuario y el nuevo email, para después actualizarlo en la base de datos.

public class UpdateUserEmail
{
    private readonly IUnitOfWork _unitOfWork;

    public UpdateUserEmail(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public async Task<bool> Execute(int userId, string newEmail)
    {
        User? user = await _unitOfWork.UserRepository.GetById(userId);
        if (user != null)
        {
            user.Email = newEmail;
            _unitOfWork.UserRepository.Update(user);
            await _unitOfWork.Save();
        }

        return true;
    }
}

Una cosa importante a tener en cuenta es que aquí utilizamos el patrón repositorio con el patrón unit of work, por lo tanto, hay que modificar el repositorio para incluir el update.

public void Update(User user)
{
    _context.Users.Update(user);
}

Y para terminar la implementación, simplemente creamos un endpoint PUT en la API.

[Route("[controller]")]
public class UsersController : Controller
{
    private readonly UpdateUserEmail _updateUserEmail;

    public UsersController(UpdateUserEmail updateUserEmail)
    {
        _updateUserEmail = updateUserEmail;
    }

    [HttpPut("update-email/{id}")]
    public async Task<bool> UpdateEmail(int id, string newEmail)
        => await _updateUserEmail.Execute(id, newEmail);
}

 

  • NOTA: Todas las bases de datos tienen lo que se llama conflicto de concurrencia, que es cuando dos acciones de actualizar están sucediendo al mismo tiempo, Entity Framework Core trae una forma de evitar dichos errores de concurrencia, pero los veremos en un post separado.



4 - Eliminar registros de una base de datos con Entity Framework core

Eliminar es tan sencillo como añadir o modificar ya que LINQ nos proporciona todo lo que necesitamos, el cual es el método Remove, al cual le tenemos que pasar primero la entidad, igual que a la hora de modificar:

public async Task Delete(int id)
{
    User? user = await _context.Users
        .FirstOrDefaultAsync(x => x.Id == id);

    if (user != null) _context.Users.Remove(user);
    await _context.SaveChangesAsync();
}

Una detalle importante a tener en cuenta es que esta acción hace lo que se llama un hard delete, osea que borra el registro de la base de datos, es muy posible que en vuestras empresas estéis haciendo Soft-Deletes, que es marcar el registro como inactivo en vez de eliminarlo completamente. Esta acción la veremos en otro post.


Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2024 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café