Del curso: .NET 5: Entity Framework Core Esencial

Operaciones asincrónicas en nuestro contexto

Los contextos de base de datos de Entity Framework Core nos proporcionan dos tipos de métodos para gestionar la base de datos: métodos síncronos y métodos asíncronos. Vamos a verlo con un ejemplo. Fíjate, estamos aquí en el controlador Home, en el HomeController en el método Index. Esté método Index devuelve un IActionResult, una interfaz. Y aquí, por ejemplo, estamos obteniendo todos los libros de la base de datos utilizando el método ToList del DbContext. Bueno, aquí estamos haciendo un montón de OrderBy, ThenBy, ThenBy, y al final estamos haciendo un ToList. Ese ToList lo que va a hacer es materializar el IEnumaerable, que hay subyacente al IQueryable. Bueno, en este caso un IOrderQueryable porque estamos haciendo OrderBy, y este ToList realmente es el que inyecta en memoria todos los libros de la base de datos. Ya no estamos trabajando contra la base de datos, sino con un objeto en memoria. Pues bien, este método es síncrono. ToList devuelve, F12, List menor que TSource. Bien, pues tenemos otra variante que es igual ToList, pero con el sufijo Async. Es decir, estamos convirtiendo esta operación de materialización de esta consulta en asíncrona. Fíjate lo que devuelve esto. Ahora es Task, menor que List, menor que TSource. Bien. Casi todos los métodos síncronos tienen su contrapartida en métodos asíncronos. Digo casi todos, porque hay algunos que no, por ejemplo, el Remove. Bien, ahora vamos a convertir todas estas operaciones en operaciones asíncronas. var books =, aquí hay que poner ahora un await para conseguir que books tenga lo que tenía antes, que es la lista de libros. Recorremos los libros, añadimos un modified al Title. ¿Y ahí qué hacemos? Un SaveChanges. igual que el ToList, también tenemos la contrapartida asíncrona, Async. Ahí lo tenemos y por tanto aquí, igual await. Uy, await, context.SaveChangesAsync Pero falta algo. Tenemos que modificar la firma del método. En lugar de IActionResult tenemos que poner asyncTask, < IActionResult, para que este método pueda ejecutar operaciones asíncronas. A ver si compila. Perfecto, ha compilado. Bien y ahora la pregunta del millón. ¿Es realmente más óptima esta forma de hacerlo que utilizar los métodos síncronos? Pues, normalmente en una aplicación web yo diría que sí y te explico por qué. Imagínate, por ejemplo, que nuestra base de datos está en un clúster de Azure, y nosotros estamos trabajando desde fuera del clúster, o en otra región. Bueno, básicamente, que por alguna razón la latencia de red sea grande. Cuando obtenemos datos de una base de datos, la latencia de red puede hacer que las operaciones de entrada y salida, pues, al final, lleven bastante tiempo. Cuando hacemos el ToListAsync, lo que estamos haciendo es materializando la consulta en hilo aparte y el hilo principal, el que está gestionando la petición HTTP, no se queda esperando, sino que como está libre, mientras se hace la operación asíncrona, puede gestionar otras peticiones. Así que realmente lo que va a tardar la consulta va a ser, básicamente, igual pero mientras está trabajando en esa consulta en lo principal puede hacer otras cosas. Por lo cual va a poder atender otras peticiones. Si fuera el método asíncrono, el hilo se quedaría aquí parado sin hacer nada, y eso no sería óptimo. Por lo cual en una web, yo diría que sí, que es más óptimo. Porque, básicamente, vamos a conseguir exprimir más el poder de nuestra máquina. Bien, vamos a ver si esto se ejecuta correctamente. Ponemos un punto de parada aquí, F9 y F5. Ahí estamos, F10, obtiene los libros, ahí los tenemos, ahora los recorremos, y guardamos. No había libros, por lo cual no ha recorrido nada, pero, como ves, funciona exactamente igual que con los métodos síncronos. También tenemos, como he dicho antes, otros muchos métodos asíncronos como, por ejemplo, FindAsync, AddAsync, FirstofDefaultAsync, SingleAsync, etc., etc.

Contenido