Operaciones con la base de datos.
ANTES DE LEER EL ARTÍCULO, POR FAVOR, LEA AQUÍ
Comenzamos
Para este articulo vamos a crear en una aplicación Blazor Server, un modelo que le llamaremos Persona con algunas propiedades, vamos a crear la migración correspondiente para actualizar nuestra base de datos y crearemos el servicio para hacer un CRUD de esa tabla.
Continuaremos donde nos quedamos en el articulo:
https://coderepo.yhd.cu/kb/agregar-entity-framework-core-a-un-proyecto-de-blazor-server/
Preparando el Modelo
En ese artículo nos quedo pendiente crear las reglas de validación que además de usarlas en las vistas para validar los datos, también son importantes para definir las características de las columnas en la base de datos; ejemplo: si una columna es nuleable o no, la longitud de los datos, etc.
Para definir reglas de validación de los datos de Persona
usamos DataAnnotations
.
En qué consiste DataAnnotations?
Básicamente, DataAnnotations
nos permite llevar a cabo validaciones de datos de acuerdo a nuestras necesidades. Esas necesidades son decoraciones que indicaremos a los miembros de nuestras entidades. Una decoración corresponderá a una validación.
En este caso vamos a definir el nombre de la tabla, marcar como requerido todos los campos, especificaremos cual será la llave primaria de nuestra tabla(aunque EF Core asume como llave primaria si la propiedad se llama Id o NombreTablaId o similares)y definiremos la longitud de nuestro campo CI. Además de poner mensajes personalizados para los errores en caso de no cumplirse la validación. La clase Persona
nos quedaría de la siguiente forma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[Table("Personas")] public class Persona { [Key] public Guid Id{ get; set;} = Guid.NewGuid(); [Required(ErrorMessage = "El nombre no puede estar vacío")] public string Nombre {get; set;} [Required(ErrorMessage = "El primer apellido no puede estar vacío")] public string PrimerApellido {get; set;} [Required(ErrorMessage = "El segundo apellido no puede estar vacío")] public string SegundoApellido {get; set;} [Required(ErrorMessage = "El CI no puede estar vacío")] [StringLength(11, ErrorMessage ="El CI tiene que ser de 11 dígitos")] [RegularExpression("^[0-9]*$", ErrorMessage = "Solo números son válidos en el CI")] public string CI {get; set;} } |
Actualizando el contexto y aplicando la migración
Necesitamos, para poder insertar la tabla en la base de datos agregar la propiedad DbSet en la clase ApplicationDbContext
. Para esto agregamos la siguiente línea:
1 |
public DbSet<Persona> Personas{ get; set; } |
Una ves terminado en la Consola del Administrador de paquetes
agregamos nuestra migración con el comando
1 2 |
add-migracion AgregarPersonas update-database |
ViewModel y su Interface
Una vez creada la tabla en la base de datos procedemos a crear el servicio que realizará todas las operaciones de CRUD. Creamos en la raíz del proyecto una carpeta con el nombre MVVM
. Dentro de la misma a mi me gusta crear dos carpetas, una de nombre ViewModels
y la otra de nombra Intefaces
,
Dentro de la carpeta Interfaces
crearemos una interfaz con el siguiente contenido:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public interface IPersonaViewModel { //Obtiene una lista con todas las personas public Task<List<Persona>> GetPersonas(); //Obtiene la persona que su Id coincide con personaId public Task<Persona> GetPersona(Guid personaId); //Agrega la persona public Task AgregarPersona(Persona persona); //Actualiza la persona que se pasa por parámetro public Task ActualizarPersona(Persona persona); //Elimina la persona que se pasa por parámetro public Task EliminarPersona(Persona persona); } |
Esta será nuestra interfaz para la clase PersonaViewModel
que la crearemos dentro de la carpeta ViewModels
e implementará todos los métodos que declaramos en la interface.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
public class PersonaViewModel : IPersonaViewModel { //Primero inyectamos el contexto para poder realizar las consultas a la base de datos private readonly ApplicationDbContext _contexto; //Lo inicializamos en el constructor public PersonaViewModel(ApplicationDbContext contexto) { _contexto = contexto; } //Obtiene una lista con todas las personas public async Task<List<Persona>> GetPersonas() { //usamos el contexto para devolver una lista de personas return await _contexto.Personas.ToListAsync(); } //Obtiene la persona que su Id coincide con personaId public async Task<Persona> GetPersona(Guid personaId) { //usamos el contexto para buscar y devolver la persona indicada return await _contexto.Personas.FindAsync(personaId); } //Agrega la persona public async Task AgregarPersona(Persona persona) { //para agregar persona, hacemos dos pasos, agregamos y confirmamos await _contexto.Personas.AddAsync(persona); await _contexto.SaveChangesAsync(); } //Actualiza la persona que se pasa por parámetro public async Task ActualizarPersona(Persona persona) { //en actualizar debemos validar si la persona existe var aux = await _contexto.Personas.FindAsync(persona.Id); if(aux == null) return; aux = persona; await _contexto.SaveChangesAsync(); } //Elimina la persona que se pasa por parámetro public async Task EliminarPersona(Persona persona) { //primero buscamos la persona y luego eliminamos el registro var aux = await _contexto.Personas.FindAsync(persona.Id); if(aux == null) return; _contexto.Personas.Remove(aux.id); await SaveChangesAsync(); } } |
Modificando Program.cs
Terminado el ViewModel
con todas las operaciones que necesitamos, solo nos queda configurarlo para que pueda ser injectado como dependencia en cualquier vista. Vamos al fichero Program.cs
, que se encuentra en la raiz de nuestor proyecto y justo debajo de la línea builder.Services.AddServerSideBlazor();
agregamos:
1 |
builder.Services.AddScoped<IPersonaViewModel, PersonaViewModel>(); |
Conclusiones
En este pequeño ejemplo, mostramos como realiza la clase que nos servirá para ejecutar todas las acciones que necesitemos desde la vista hasta la base de datos. En otros artículos explicaremos como usar este ViewModel en una vista usando DevExpress