Loupe

[Win8.1, WP8.1] Stocker ses données avec SQLite en C#

Il existe de nombreuses techniques pour stocker des informations dans un environnement Win8 et WP8, en voici quelques-unes :

  • sauvegarde dans les “AppSettings” de l’application,
  • dans un fichier (xml ou non) stocké dans le local Storage de l’application
  • sur internet,
  • dans une base locale,

Chacune d’elle a ses avantages et ses inconvénients et doit être choisie en fonction de plusieurs critères :

  • les contraintes liées à l’application (fonctionnement online/offline),
  • le type, la taille et la complexité des données qui doivent être pérennisées,

Pourquoi utiliser SQLite ?

SQLite est souvent le choix effectué par les développeurs pour stocker leurs données, simple à mettre en place, elle permet de stocker des données plutôt complexes et de les gérer à la manière SQL (via des requêtes) ou via LINQ. Ces méthodes étant connues et appréciées par les développeurs C#.

Une fois les données stockées dans la base SQLite, l’application peut tout à fait fonctionner en mode hors-ligne, ce qui peut être une nécessité.

Comment mettre en place SQLite ?

Il faut dans un premier temps, télécharger et installer le package VSIX (disponible à l’adresse suivante : https://sqlite.org/download.html) correspondant à la plateforme sur laquelle vous souhaitez intégrer SQLite.

Une fois le VSIX installé, vous pourrez ajouter en référence (dans l’onglet “Extensions” du SDK cible). Une fois cette référence ajoutée, ajoutez une dernière référence via Nuget au wrapper SQLite pour .Net “sqlite-net” (détails disponibles à l’adresse suivante : https://github.com/praeclarum/sqlite-net).

L’ajout de cette dernière référence, ajoute deux classes  SQLite et SQLiteAsync qui vont vous permettre de plus simplement interagir avec votre base de données SQLite. Ces deux classes exposent les mêmes méthodes (connexion, CRUD …) mais la seconde les expose de manière asynchrone et est donc à privilégier pour vos applications.

Comment utiliser SQLite ?

Je vous conseille de faire une classe qui regroupe les méthodes permettant d’interagir avec la base, dans mon cas, cette classe sera appelée SQLiteHelper.

Dans mon exemple, je vais devoir stocker dans ma base SQLite des clients (Customer) et des achats (Purchase), voici comment procéder.

Etape 1 : Créer la connexion

var connexion = new SQLiteAsyncConnection("sqlitedatabaseName");

C’est tout ? Et bien oui, cela va vous créer le fichier sur lequel SQLite va se baser pour stocker vos données.

Etape 2 : Ajouter les tables

public class Customer
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public string DisplayName { get; set; }
    public DateTime DateOfBirth { get; set; }
}

public class Purchase
{
    [PrimaryKey, AutoIncrement]
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public DateTime PurchaseDate { get; set; }
}

Voici donc les deux classes que je souhaite stocker dans SQLite. Vous aurez remarqué les attributs spéciaux PrimaryKey et AutoIncrement qui sont fournis par SQLite pour lui spécifier le rôle de certaines propriétés. Dans mon cas, je souhaite que les propriétés “Id” de mes classes soient des clés primaires et soient incrémentées automatiquement par SQLite.

Vous disposez donc de deux façons pour créer vos tables soit une par une, soit de manière groupée :

// Création des tables une par une, basées sur les classes Customer et Purchase
await connexion.CreateTableAsync<Customer>();
await connexion.CreateTableAsync<Purchase>();
// Création groupée des tables, basées sur les classes Customer et Purchase
await connexion.CreateTablesAsync<Customer, Purchase>();

Etape 3 : CRUD des données

Create

Ajout d’un client et d’un achat :

// Creation du Customer
var currentCustomer = new Customer()
{
    DisplayName = "Cristiano Ronaldo",
    DOB = new DateTime(1985, 2, 5)
};
// Ajout dans la base de données - qui va automatiquement créer l'Id
await connexion.InsertAsync(currentCustomer);

// Ajout d'un Purchase pour le customer créé ci-dessus
await connexion.InsertAsync(new Purchase()
{
    CustomerId = currentCustomer.Id,
    PurchaseDate = DateTime.Now
});

Il existe également une méthode “InsertAllAsync “ qui permet de faire de l’ajout en masse en lui passant une collection.

Read

Recherche des clients ayant dans leur nom “Ronaldo” en utilisant Linq :

await connexion.Table<Customer>().Where(c => c.DisplayName.Contains("Ronaldo")).ToListAsync();

Update

Recherche du client, et mise à jour des informations:

var customer = await connexion.Table<Customer>().Where(c => c.DisplayName.Contains("Ronaldo")).FirstOrDefaultAsync();
if(customer != null)
{
    customer.DisplayName = "Teddy Desmas";
    customer.DOB = new DateTime(1991, 12, 11);
    await connexion.UpdateAsync(customer);
}

Il existe également une méthode “UpdateAllAsync “ qui permet de faire de la mise à jour en masse en lui passant une collection.

Delete

Recherche du client à supprimer et suppression de celui-ci :

var customer = await connexion.Table<Customer>().Where(c => c.DisplayName.Contains("Desmas")).FirstOrDefaultAsync();
if (customer != null)
{
    await connexion.DeleteAsync(customer);
}

Pour les plus attentifs, vous aurez remarqué que j’ai supprimé mon client alors qu’il avait un achat. Dans les bases de données classiques, cette requête n’aurait pas fonctionné puisque l’on aurait mis une relation entre Customer et Purchase. Etant donné que sqlite-net ne gère pas nativement les relations de type “Foreign Key”, si je souhaite garder l’intégrité de mes données, je vais devoir dans mon exemple supprimer les achats liés à mon client avant de le supprimer lui-même.

 

Voilà, vous avez toutes les informations nécessaires pour commencer à utiliser SQLite dans vos applications Windows 8.1 ou Windows Phone 8.1.

Une dernière information utile, vous pouvez télécharger le logiciel SQLite DB Browser (http://sqlitebrowser.org/) pour pouvoir observer les changements que vous effectuez sur vos enregistrements.

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus