Almacenamiento de datos en una base de datos local de SQLite.NET
En este inicio rápido aprenderá a:
- Almacenar datos de forma local en una base de datos de SQLite.NET.
El inicio rápido lo guía durante el proceso de almacenamiento de datos en una base de datos de SQLite.NET local desde una aplicación de Xamarin.Forms Shell. A continuación se muestra la aplicación final:
Requisitos previos
Antes de intentar este inicio rápido, debe completar correctamente el inicio rápido anterior.
Actualizar la aplicación con Visual Studio
Inicie Visual Studio y abra la solución Notes.
En el Explorador de soluciones, haga clic con el botón derecho en la solución Notes y seleccione Administrar paquetes de NuGet para la solución… :
En el Administrador de paquetes de NuGet, seleccione la pestaña Examinar y busque el paquete de NuGet sqlite-net-pcl.
Advertencia
Hay diversos paquetes NuGet con nombres similares. El paquete correcto tiene estos atributos:
- Autores: SQLite-net
- Vínculo de NuGet: sqlite-net-pcl
A pesar del nombre del paquete, este paquete NuGet puede usarse en proyectos de .NET Standard.
En el Administrador de paquetes de NuGet, seleccione el paquete sqlite-net-pcl correcto, active la casilla Proyecto y haga clic en el botón Instalar para agregarlo a la solución:
Este paquete se usará para incorporar operaciones de base de datos en la aplicación y se agregará a todos los proyectos de la solución.
Importante
SQLite.NET es una biblioteca de terceros compatible con el repositorio praeclarum/sqlite-net.
Cierre el Administrador de paquetes NuGet.
En el Explorador de soluciones, en el proyecto Notes, abra Note.cs en la carpeta Modelos y reemplace el código existente por el siguiente:
using System; using SQLite; namespace Notes.Models { public class Note { [PrimaryKey, AutoIncrement] public int ID { get; set; } public string Text { get; set; } public DateTime Date { get; set; } } }
Esta clase define un modelo
Note
que almacenará los datos sobre cada nota en la aplicación. La propiedadID
está marcada con los atributosPrimaryKey
yAutoIncrement
para garantizar que cada instancia deNote
en la base de datos de SQLite.NET tenga un identificador único proporcionado por SQLite.NET.Presione CTRL+S para guardar los cambios en Notes.cs.
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Explorador de soluciones, agregue una nueva carpeta denominada Datos al proyecto Notes.
En el Explorador de soluciones, en el proyecto Notes, agregue una nueva clase denominada NoteDatabase a la carpeta Datos.
En NoteDatabase.cs, reemplace el código existente con el siguiente:
using System.Collections.Generic; using System.Threading.Tasks; using SQLite; using Notes.Models; namespace Notes.Data { public class NoteDatabase { readonly SQLiteAsyncConnection database; public NoteDatabase(string dbPath) { database = new SQLiteAsyncConnection(dbPath); database.CreateTableAsync<Note>().Wait(); } public Task<List<Note>> GetNotesAsync() { //Get all notes. return database.Table<Note>().ToListAsync(); } public Task<Note> GetNoteAsync(int id) { // Get a specific note. return database.Table<Note>() .Where(i => i.ID == id) .FirstOrDefaultAsync(); } public Task<int> SaveNoteAsync(Note note) { if (note.ID != 0) { // Update an existing note. return database.UpdateAsync(note); } else { // Save a new note. return database.InsertAsync(note); } } public Task<int> DeleteNoteAsync(Note note) { // Delete a note. return database.DeleteAsync(note); } } }
Esta clase contiene código para crear la base de datos, leer datos de ella, escribir datos en ella y eliminarlos. El código usa API asincrónicas de SQLite.NET que mueven las operaciones de base de datos a subprocesos en segundo plano. Además, el constructor
NoteDatabase
toma la ruta de acceso del archivo de base de datos como un argumento. La claseApp
proporcionará esta ruta de acceso en el paso siguiente.Presione CTRL+S para guardar los cambios en NoteDatabase.cs.
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Explorador de soluciones, en el proyecto Notes, expanda App.xaml y haga doble clic en App.xaml.cs para abrirlo. Después, reemplace el código existente con el siguiente:
using System; using System.IO; using Notes.Data; using Xamarin.Forms; namespace Notes { public partial class App : Application { static NoteDatabase database; // Create the database connection as a singleton. public static NoteDatabase Database { get { if (database == null) { database = new NoteDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Notes.db3")); } return database; } } public App() { InitializeComponent(); MainPage = new AppShell(); } protected override void OnStart() { } protected override void OnSleep() { } protected override void OnResume() { } } }
Este código define una propiedad
Database
que crea una instancia deNoteDatabase
como singleton, y pasa el nombre de archivo de la base de datos como argumento al constructorNoteDatabase
. La ventaja de exponer la base de datos como un singleton es que se crea una conexión de base de datos única que se mantiene abierta mientras la aplicación se ejecuta, lo que evita el gasto de abrir y cerrar el archivo de base de datos cada vez que se realiza una operación de base de datos.Presione CTRL+S para guardar los cambios en App.xaml.cs.
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Explorador de soluciones, en el proyecto Notes, expanda NotesPage.xaml en la carpeta Vistas y abra NotesPage.xaml.cs. Después, reemplace los métodos
OnAppearing
yOnSelectionChanged
con el código siguiente:protected override async void OnAppearing() { base.OnAppearing(); // Retrieve all the notes from the database, and set them as the // data source for the CollectionView. collectionView.ItemsSource = await App.Database.GetNotesAsync(); } async void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection != null) { // Navigate to the NoteEntryPage, passing the ID as a query parameter. Note note = (Note)e.CurrentSelection.FirstOrDefault(); await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}"); } }
El método
OnAppearing
rellena el elementoCollectionView
con todas las notas almacenadas en la base de datos. El métodoOnSelectionChanged
navega hasta el objetoNoteEntryPage
y pasa la propiedadID
del objetoNote
seleccionado como un parámetro de consulta.Presione CTRL+S para guardar los cambios en NotesPage.xaml.cs.
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Explorador de soluciones, expanda NoteEntryPage.xaml en la carpeta Vistas y abra NoteEntryPage.xaml.cs. Después, reemplace los métodos
LoadNote
,OnSaveButtonClicked
yOnDeleteButtonClicked
por el código siguiente:async void LoadNote(string itemId) { try { int id = Convert.ToInt32(itemId); // Retrieve the note and set it as the BindingContext of the page. Note note = await App.Database.GetNoteAsync(id); BindingContext = note; } catch (Exception) { Console.WriteLine("Failed to load note."); } } async void OnSaveButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; note.Date = DateTime.UtcNow; if (!string.IsNullOrWhiteSpace(note.Text)) { await App.Database.SaveNoteAsync(note); } // Navigate backwards await Shell.Current.GoToAsync(".."); } async void OnDeleteButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; await App.Database.DeleteNoteAsync(note); // Navigate backwards await Shell.Current.GoToAsync(".."); }
NoteEntryPage
utiliza el métodoLoadNote
para recuperar la nota de la base de datos, cuyo identificador se pasó como parámetro de consulta a la página, y la almacena como un objetoNote
en el objetoBindingContext
de la página. Cuando se ejecuta el controlador de eventosOnSaveButtonClicked
, la instancia deNote
se guarda en la base de datos y la aplicación regresa a la página anterior. Cuando se ejecuta el controlador de eventosOnDeleteButtonClicked
, la instancia deNote
se elimina de la base de datos y la aplicación regresa a la página anterior.Presione CTRL+S para guardar los cambios en NoteEntryPage.xaml.cs.
Compile y ejecute el proyecto en cada plataforma. Para más información, vea Compilación del inicio rápido.
En NotesPage presione el botón Agregar para navegar hasta NoteEntryPage y escriba una nota. Después de guardar la nota, la aplicación volverá a NotesPage.
Escriba varias notas, de longitud variable, para observar el comportamiento de la aplicación. Cierre la aplicación y vuelva a iniciarla para asegurarse de que las notas que escribió se guardaron en la base de datos.
Actualizar la aplicación con Visual Studio para Mac
Inicie Visual Studio para Mac y abra la solución Notes.
En el Panel de solución, haga clic con el botón derecho en la solución Notes y seleccione Administrar paquetes de NuGet… :
En el cuadro de diálogo Administrar paquetes de NuGet, seleccione la pestaña Examinar y busque el paquete de NuGet sqlite-net-pcl.
Advertencia
Hay diversos paquetes NuGet con nombres similares. El paquete correcto tiene estos atributos:
- Autores: SQLite-net
- Vínculo de NuGet: sqlite-net-pcl
A pesar del nombre del paquete, este paquete NuGet puede usarse en proyectos de .NET Standard.
En el cuadro de diálogo Administrar paquetes de NuGet, seleccione el paquete sqlite-net-pcl y haga clic en el botón Agregar paquete para agregarlo a la solución:
Este paquete se usará para incorporar operaciones de bases de datos en la aplicación.
En el cuadro de diálogo Seleccionar proyectos, asegúrese de que todas las casillas estén activadas y presione el botón Aceptar:
Esto agregará el paquete de NuGet a cada proyecto de la solución.
En el Panel de solución, en el proyecto Notes, abra Note.cs en la carpeta Modelos y reemplace el código existente por el siguiente:
using System; using SQLite; namespace Notes.Models { public class Note { [PrimaryKey, AutoIncrement] public int ID { get; set; } public string Text { get; set; } public DateTime Date { get; set; } } }
Esta clase define un modelo
Note
que almacenará los datos sobre cada nota en la aplicación. La propiedadID
está marcada con los atributosPrimaryKey
yAutoIncrement
para garantizar que cada instancia deNote
en la base de datos de SQLite.NET tenga un identificador único proporcionado por SQLite.NET.Para guardar los cambios en Note.cs, seleccione Archivo > Guardar (o bien presione ⌘ + S).
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Panel de solución, agregue una nueva carpeta denominada Datos al proyecto Notes.
En el Panel de solución, en el proyecto Notes, agregue una nueva clase denominada NoteDatabase a la carpeta Datos.
En NoteDatabase.cs, reemplace el código existente con el siguiente:
using System.Collections.Generic; using System.Threading.Tasks; using SQLite; using Notes.Models; namespace Notes.Data { public class NoteDatabase { readonly SQLiteAsyncConnection database; public NoteDatabase(string dbPath) { database = new SQLiteAsyncConnection(dbPath); database.CreateTableAsync<Note>().Wait(); } public Task<List<Note>> GetNotesAsync() { //Get all notes. return database.Table<Note>().ToListAsync(); } public Task<Note> GetNoteAsync(int id) { // Get a specific note. return database.Table<Note>() .Where(i => i.ID == id) .FirstOrDefaultAsync(); } public Task<int> SaveNoteAsync(Note note) { if (note.ID != 0) { // Update an existing note. return database.UpdateAsync(note); } else { // Save a new note. return database.InsertAsync(note); } } public Task<int> DeleteNoteAsync(Note note) { // Delete a note. return database.DeleteAsync(note); } } }
Esta clase contiene código para crear la base de datos, leer datos de ella, escribir datos en ella y eliminarlos. El código usa API asincrónicas de SQLite.NET que mueven las operaciones de base de datos a subprocesos en segundo plano. Además, el constructor
NoteDatabase
toma la ruta de acceso del archivo de base de datos como un argumento. La claseApp
proporcionará esta ruta de acceso en el paso siguiente.Para guardar los cambios en NoteDatabase.cs, seleccione Archivo > Guardar (o bien presione ⌘ + S).
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Panel de solución, en el proyecto Notes, expanda App.xaml y haga doble clic en App.xaml.cs para abrirlo. Después, reemplace el código existente con el siguiente:
using System; using System.IO; using Notes.Data; using Xamarin.Forms; namespace Notes { public partial class App : Application { static NoteDatabase database; // Create the database connection as a singleton. public static NoteDatabase Database { get { if (database == null) { database = new NoteDatabase(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Notes.db3")); } return database; } } public App() { InitializeComponent(); MainPage = new AppShell(); } protected override void OnStart() { } protected override void OnSleep() { } protected override void OnResume() { } } }
Este código define una propiedad
Database
que crea una instancia deNoteDatabase
como singleton, y pasa el nombre de archivo de la base de datos como argumento al constructorNoteDatabase
. La ventaja de exponer la base de datos como un singleton es que se crea una conexión de base de datos única que se mantiene abierta mientras la aplicación se ejecuta, lo que evita el gasto de abrir y cerrar el archivo de base de datos cada vez que se realiza una operación de base de datos.Para guardar los cambios en App.xaml.cs, seleccione Archivo > Guardar (o bien presione ⌘ + S).
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Panel de solución, en el proyecto Notes, expanda NotesPage.xaml en la carpeta Vistas y abra NotesPage.xaml.cs. Después, reemplace los métodos
OnAppearing
yOnSelectionChanged
con el código siguiente:protected override async void OnAppearing() { base.OnAppearing(); // Retrieve all the notes from the database, and set them as the // data source for the CollectionView. collectionView.ItemsSource = await App.Database.GetNotesAsync(); } async void OnSelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.CurrentSelection != null) { // Navigate to the NoteEntryPage, passing the ID as a query parameter. Note note = (Note)e.CurrentSelection.FirstOrDefault(); await Shell.Current.GoToAsync($"{nameof(NoteEntryPage)}?{nameof(NoteEntryPage.ItemId)}={note.ID.ToString()}"); } }
El método
OnAppearing
rellena el elementoCollectionView
con todas las notas almacenadas en la base de datos. El métodoOnSelectionChanged
navega hasta el objetoNoteEntryPage
y pasa la propiedadID
del objetoNote
seleccionado como un parámetro de consulta.Para guardar los cambios en NotesPage.xaml.cs, seleccione Archivo > Guardar (o bien presione ⌘ + S).
Advertencia
Actualmente, la aplicación no se compilará debido a errores que se corregirán en los pasos subsiguientes.
En el Panel de solución, expanda NoteEntryPage.xaml en la carpeta Vistas y abra NoteEntryPage.xaml.cs. Después, reemplace los métodos
LoadNote
,OnSaveButtonClicked
yOnDeleteButtonClicked
por el código siguiente:async void LoadNote(string itemId) { try { int id = Convert.ToInt32(itemId); // Retrieve the note and set it as the BindingContext of the page. Note note = await App.Database.GetNoteAsync(id); BindingContext = note; } catch (Exception) { Console.WriteLine("Failed to load note."); } } async void OnSaveButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; note.Date = DateTime.UtcNow; if (!string.IsNullOrWhiteSpace(note.Text)) { await App.Database.SaveNoteAsync(note); } // Navigate backwards await Shell.Current.GoToAsync(".."); } async void OnDeleteButtonClicked(object sender, EventArgs e) { var note = (Note)BindingContext; await App.Database.DeleteNoteAsync(note); // Navigate backwards await Shell.Current.GoToAsync(".."); }
NoteEntryPage
utiliza el métodoLoadNote
para recuperar la nota de la base de datos, cuyo identificador se pasó como parámetro de consulta a la página, y la almacena como un objetoNote
en el objetoBindingContext
de la página. Cuando se ejecuta el controlador de eventosOnSaveButtonClicked
, la instancia deNote
se guarda en la base de datos y la aplicación regresa a la página anterior. Cuando se ejecuta el controlador de eventosOnDeleteButtonClicked
, la instancia deNote
se elimina de la base de datos y la aplicación regresa a la página anterior.Para guardar los cambios en NoteEntryPage.xaml.cs, seleccione Archivo > Guardar (o bien presione ⌘ + S).
Compile y ejecute el proyecto en cada plataforma. Para más información, vea Compilación del inicio rápido.
En NotesPage presione el botón Agregar para navegar hasta NoteEntryPage y escriba una nota. Después de guardar la nota, la aplicación volverá a NotesPage.
Escriba varias notas, de longitud variable, para observar el comportamiento de la aplicación. Cierre la aplicación y vuelva a iniciarla para asegurarse de que las notas que escribió se guardaron en la base de datos.
Pasos siguientes
En este inicio rápido ha aprendido a:
- Almacenar datos de forma local en una base de datos de SQLite.NET.
Continúe con el inicio rápido siguiente para aplicar estilos a la aplicación con los estilos XAML.