Stocker des données localement avec SQLite
SQLite est utile lorsque vous avez des données relationnelles. Supposons que vous créez une application de réseaux sociaux. Vous devez stocker des informations sur les abonnés dans l’application. Ces données incluent un identifiant unique pour chaque utilisateur, ainsi que son nom. Vous pouvez facilement modéliser ce type de relation dans une base de données SQLite.
Dans cette unité, vous découvrez comment utiliser SQLite dans une application .NET MAUI à l’aide de SQLite-net.
Qu’est-ce que SQLite ?
SQLite est une base de données locale multiplateforme légère devenue une norme industrielle pour les applications mobiles. SQLite ne nécessite pas de serveur. La base de données est stockée dans un fichier disque unique sur le système de fichiers de l’appareil. Toutes les opérations de lecture et d’écriture sont exécutées directement sur le fichier de disque SQLite.
Les bibliothèques natives SQLite sont intégrées à Android et iOS par défaut. Toutefois, le moteur prend uniquement en charge l’API C/C++. Ce scénario n’est pas idéal pour les développeurs .NET, qui veulent un moyen de faire interagir SQLite et .NET.
Qu’est-ce que SQLite-net ?
Les développeurs .NET peuvent utiliser plusieurs wrappers C# autour du moteur SQLite natif. De nombreux développeurs .NET utilisent un wrapper C# populaire appelé SQLite-net.
SQLite-net est un mappeur relationnel objet. Il permet de simplifier le processus de définition de schémas de bases de données en vous laissant utiliser comme schémas les modèles définis dans nos projets.
Prenons l’exemple de la classe suivante qui modélise un User :
class User
{
public int Id { get; set; }
public string Username { get; set; }
...
}
En utilisant un mappeur relationnel objet, vous pouvez prendre cette classe User initiale et créer une table de base de données appelée User qui comporte des colonnes pour les champs Id et Username dans cette classe.
SQLite-net est livré sous la forme d’un package NuGet. Vous devez ajouter le package sqlite-net-pcl à vos applications pour l’utiliser.
Comment se connecter à une base de données SQLite
Vous pouvez établir une connexion à une base de données SQLite via un objet SQLiteConnection. Cette classe est définie dans l’espace de noms SQLite, avec les autres types et méthodes fournis par SQLite. Quand vous instanciez cet objet, vous devez passer le nom de fichier pour le fichier de base de données. Le constructeur ouvre ensuite le fichier s’il existe, ou le crée s’il n’existe pas.
Le code suivant montre un exemple :
using SQLite;
...
string filename = ...
SQLiteConnection conn = new SQLiteConnection(filename);
Rappelez-vous que filename doit pointer vers un emplacement dans le bac à sable de l’application.
Comment créer une table
Rappelez-vous que SQLite-net est un mappeur relationnel objet, ce qui signifie que vous pouvez créer votre schéma de base de données à partir de classes C#. SQLite-net peut générer une table de base de données à partir d’une classe C# ordinaire, mais il existe de nombreux attributs que vous pouvez ajouter à une classe pour fournir plus de métadonnées. Ces métadonnées aident SQLite à faire respecter des caractéristiques telles que l’unicité, ainsi qu’à appliquer des contraintes à vos données.
Les attributs disponibles incluent :
-
Table: Spécifiez le nom de la table si vous voulez qu’il soit différent du nom de la classe. -
PrimaryKey: Spécifiez qu’une colonne est la clé primaire. -
AutoIncrement: Spécifiez que la valeur d’une colonne doit augmenter automatiquement quand une nouvelle ligne est insérée. -
Column: Spécifiez le nom d’une colonne si vous voulez qu’il soit différent du nom de la propriété. -
MaxLength: Spécifiez le nombre maximal de caractères pouvant être utilisés dans la colonne. -
Unique: Indiquez que la valeur de la colonne doit être unique dans toutes les autres lignes.
Le code suivant montre la version mise à jour de la classe User qui applique ces attributs :
[Table("user")]
public class User
{
// PrimaryKey is typically numeric
[PrimaryKey, AutoIncrement, Column("_id")]
public int Id { get; set; }
[MaxLength(250), Unique]
public string Username { get; set; }
...
}
Après avoir défini votre classe C#, appelez la méthode générique CreateTable sur la classe SQLiteConnection pour générer la table dans la base de données. Spécifiez la classe en tant que paramètre de type. Voici un exemple :
SQLiteConnection conn = new SQLiteConnection(filename);
conn.CreateTable<User>();
Si la table existe déjà dans la base de données, la méthode CreateTable vérifie le schéma pour voir si des modifications ont été apportées. Si c’est le cas, l’opération tente de mettre à jour le schéma de base de données.
Comment effectuer des opérations de lecture et d’écriture de base
Après avoir créé une table, vous pouvez commencer à interagir avec celle-ci. Pour ajouter une ligne, utilisez la méthode Insert sur l’instance SQLiteConnection et fournissez un objet du type approprié contenant les données à insérer. Le code suivant montre comment ajouter une nouvelle ligne à la table User :
public int AddNewUser(User user)
{
int result = conn.Insert(user);
return result;
}
La méthode Insert retourne un int représentant le nombre de lignes insérées dans la table. Dans ce cas, ce nombre est 1.
Pour extraire des lignes d’une table, utilisez la méthode Table. Cette méthode retourne une collection d’objets (qui peut être vide) :
public List<User> GetAllUsers()
{
List<User> users = conn.Table<User>().ToList();
return users;
}
La méthode Table retourne un objet TableQuery\<T>. Pour obtenir une List, utilisez la méthode ToList comme indiqué dans l’exemple précédent.
Exécuter une requête SQLite avec LINQ
La méthode Table extrait toutes les lignes d’une table. Dans la plupart des cas, vous souhaitez retourner uniquement un sous-ensemble des lignes correspondant à un ensemble de critères spécifiés. Pour ces tâches, utilisez LINQ avec SQLite-net.
SQLite-net prend en charge de nombreuses requêtes LINQ courantes, à savoir :
WhereTakeSkipOrderByOrderByDescendingThenByElementAtFirstFirstOrDefaultThenByDescendingCount
Avec ces méthodes, vous pouvez utiliser la syntaxe de méthode d’extension ou la syntaxe C# LINQ. Par exemple, voici un extrait de code qui vous permet de récupérer les détails d’un utilisateur spécifié :
public User GetByUsername(string username)
{
var user = from u in conn.Table<User>()
where u.Username == username
select u;
return user.FirstOrDefault();
}
Mettre à jour et supprimer des lignes
Vous mettez à jour une ligne à l’aide de la méthode SQLiteConnection de l’objet Update. Vous fournissez un objet définissant la ligne à mettre à jour avec ses nouvelles valeurs. La méthode Update modifie la ligne qui a la même valeur de clé primaire que l’objet fourni. La valeur retournée correspond au nombre de lignes modifiées. Si cette valeur est égale à zéro, aucune ligne avec une clé primaire correspondante n’a été trouvée, et rien n’a été mis à jour. L’extrait de code suivant montre cette méthode à l’œuvre :
public int UpdateUser(User user)
{
int result = 0;
result = conn.Update(user);
return result;
}
Supprimez les lignes d’une table avec la méthode SQLiteConnection de l’objet Delete. La forme la plus simple de cette méthode prend la clé primaire de l’élément à supprimer comme paramètre, comme indiqué dans l’exemple ci-dessous. Cette forme de la méthode Delete est générique et nécessite un paramètre de type. La valeur retournée est le nombre de lignes supprimées de la table :
public int DeleteUser(int userID)
{
int result = 0;
result = conn.Delete<User>(userID);
return result;
}