Une classe de base pour manipuler SQLite facilement en C#

icon Tags de l'article : ,

Avril 03, 2015
Hello à tous,

Aujourd'hui je vais vous parler de SQLite. Lors d'un projet récent, j'ai eu à manipuler une BDD SQLite en C#. Pour cela j'ai créé une classe qui peut vous intéresser.

La première étape, pour manipuler du SQLite, est d'installer le package Nuget SQLite (et ses prérequis).

Ensuite, j'ai créé cette classe abstraite :

using System;
using System.Collections.Generic;
using System.Data.SQLite;

public abstract class BaseDA<T>
{
	public string ConnectionString { get; set; }

	public BaseDA(string connectionString)
	{
		this.ConnectionString = connectionString;
	}

	protected T GetUniqueItem(string sql, Func<SQLiteDataReader, T> mappingMethod)
	{
		var connection = new SQLiteConnection(this.ConnectionString);

		try
		{
			var command = new SQLiteCommand(sql, connection);

			var reader = command.ExecuteReader();

			if (reader.Read())
			{
				return mappingMethod(reader);
			}
		}
		finally
		{
			connection.Close();
		}

		return default(T);
	}

	protected IEnumerable<T> GetItems(string sql, Func<SQLiteDataReader, T> mappingMethod)
	{
		var connection = new SQLiteConnection(this.ConnectionString);

		try
		{
			var command = new SQLiteCommand(sql, connection);

			var reader = command.ExecuteReader();

			var result = new List<T>();

			while (reader.Read())
			{
				result.Add(mappingMethod(reader));
			}

			return result;
		}
		finally
		{
			connection.Close();
		}
	}

	protected int ExecuteNonQuery(string sql)
	{
		var connection = new SQLiteConnection(this.ConnectionString);

		try
		{
			var command = new SQLiteCommand(sql, connection);

			return command.ExecuteNonQuery();
		}
		finally
		{
			connection.Close();
		}
	}
}

Comme vous le voyez, cette classe contient 3 méthodes basiques me permettant de requêter facilement ma BDD SQLite.

Je n'ai plus qu'à créer une classe qui hérite de cette classe abstraite, pour, par exemple, gérer mes utilisateurs :

using ApiManager.BusinessEntities;
using System.Collections.Generic;
using System.Data.SQLite;

public class UserDA : BaseDA<UserBE>
{
	public UserDA(string connectionString) : base(connectionString)
	{
	}

	public UserBE GetUserByLogin(string login)
	{
		var sql = string.Format("SELECT * FROM User WHERE Login='{0}'", login);

		return GetUniqueItem(sql, this.MapUser);
	}

	public IEnumerable<UserBE> GetUsers()
	{
		var sql = "SELECT * FROM User";

		return (IEnumerable<UserBE>)GetItems(sql, this.MapUser);
	}

	public bool AddUser(UserBE user)
	{
		var sql = string.Format("INSERT INTO User VALUES ('{0}', '{1}', {2})", user.Login, user.Password, user.IsAdmin ? "1" : "0");

		return ExecuteNonQuery(sql) == 1;
	}

	public bool DeleteUser(int idUser)
	{
		var sql = string.Format("DELETE FROM User WHERE Id = {0}", idUser);

		return ExecuteNonQuery(sql) == 1;
	}

	private UserBE MapUser(SQLiteDataReader reader)
	{
		return new UserBE()
		{
			Id = (int)reader["Id"],
			Login = reader["Login"].ToString(),
			IsAdmin = (bool)reader["IsAdmin"],
			Password = reader["Password"].ToString()
		};
	}
}

Voilà, en résumé :
  • Ma classe mère, BaseDA, contient 3 méthodes pour requêter la BDD à partir de la connection string passée dans le constructeur.
  • Ensuite on crée une classe qui hérite de BaseDA et qui appelera le constructeur de cette dernière.
  • Enfin, on n'a plus qu'à appeler les méthodes de la classe mère avec le SQL désiré (et la méthode de mapping reader => objet dans le cas des méthodes de Get)

Voilà, on ne sait jamais, ça vous servira peut-être un jour !

Bonne journée à tous... Et bon weekend !