Xamarin.Forms: Creando una BBDD con Entity Framework Core SQLite – 2da parte

Aquí podéis encontrar la primera primera parte de esta serie de posts

Si en algún momento habéis desarrollado una aplicación móvil en Xamarin.Forms con una base de datos local utilizando Entity Framework Core SQLite para ello, os habréis encontrado con el molesto problema de tener que desinstalar la aplicación móvil del dispositivo cada vez que se actualiza el modelo de datos para que la base de datos cuente con los nuevos campos.

Hoy os contamos cómo realizar las migraciones en un proyecto de esta tipología y así poder actualizar la base de datos sin necesidad de desinstalar la aplicación. Para ello partiremos del código de nuestro post anterior en donde se explica cómo crear una aplicación de Xamarin.Forms con una base de datos local utilizando Entity Framework Core SQLite. Podéis descargar el código correspondiente aquí.

Para iniciar nuestra implementación, añadiremos a la solución un proyecto de consola en .NET Core:

Una vez creado, añadiremos la referencia al proyecto en el que tenemos nuestro DbContext. En nuestro caso, EFCoreSQLiteXamFormsApp.

A continuación agregaremos al proyecto de migraciones los siguientes paquetes nuget:

  • EntityFrameworkCore.Tools
  • EntityFrameworkCore.Design
  • EntityFrameworkCore.Sqlite

Ahora vamos a modificar nuestra clase DatabaseContext:

  1. Comenzamos añadiendo un nuevo constructor, que utilizaremos más tarde desde el proyecto de las migraciones que hemos creado:
______

  private string _dbPath;
public DataBaseContext(string dbPath)
        	{
            	_dbPath = dbPath;
        	}
  1. Actualizamos el contenido del método OnConfiguring al siguiente código:
______
    
    
   var dbPath = string.IsNullOrWhiteSpace(_dbPath)
                ? DataBaseService.GetDbPath()
                : _dbPath;
            optionsBuilder.UseSqlite($"Filename={dbPath}");


De este modo, en el caso de que la variable dbPath tenga valor (cuando la ejecución provenga del proyecto de consola de las migraciones) asignaremos como ruta el valor que se pasa en el constructor. Si la aplicación se está ejecutando en un dispositivo, la variable _dbPath no tendrá valor y la ruta para la BB.DD. se obtiene del servicio de plataforma DataBaseService.

3. Y finalmente cambiamos la línea:

______

  dbContext.Database.EnsureCreated();

por la siguiente:

______

  
_dbContext.Database.MigrateAsync();

para poder llevar a cabo las migraciones creadas cuando la aplicación se ejecute en el dispositivo.

Volvemos a nuestro proyecto de migraciones y creamos la siguiente clase para indicar al proceso de migración qué contexto utilizar para su creación:

______
  
public class DesignTimeDataBaseContext :
IDesignTimeDbContextFactory
{
public DataBaseContext CreateDbContext(string[] args)
{
string databasePath = $"{Directory.GetCurrentDirectory()}\\{DbConstants.DB_NAME}";
return new DataBaseContext(databasePath);
}
}

Ya tenemos configurado nuestro proyecto para comenzar a crear migraciones.

Pulsamos sobre el proyecto con el botón derecho y seleccionamos

Tools -> Open in Terminal para abrir la el proyecto en la terminal de Visual Studio.

Se abre la ventana del Terminal. Mediante comandos, posicionarse en el directorio que contiene el proyecto de las migraciones y el proyecto en el que se encuentra nuestro contexto y ejecutar el siguiente comando:

______

dotnet ef migrations add InitialMigration --project EFCoreSQLiteXamFormsApp --startup-project EFCoreSQLiteXamFormsApp.Migrations --verbose

Al ejecutarlo, se crea una carpeta en el proyecto en el que tenemos el contexto. La carpeta, nombrada como Migrations, contiene nuestra primera migración y la foto actual del contexto:

Ahora ejecutemos la aplicación con nuestra primera migración para, a continuación hacer cambios en nuestro modelo de datos. Vamos a añadir un nuevo campo al modelo Patient:

______

	public string EmailAddress { get; set; }

Ejecutamos de nuevo el comando anterior, modificando el nombre de InitialMigration por el que queramos asignar:

______

 dotnet ef migrations add UpdatePatientModel --project EFCoreSQLiteXamFormsApp --startup-project EFCoreSQLiteXamFormsApp.Migrations --verbose

Tras esto, se añaden a la carpeta Migrations la nueva migración:

Lanzamos la aplicación de nuevo, y al abrir la BBDD se puede comprobar que se ha añadido la nueva columna a la entidad Patient.

¡Ya tenemos las migraciones funcionando en nuestro proyecto!

Artículo escrito por nuestros cracks del equipo movilidad.

Puedes encontrar todo el código en nuestro github.