Table des matières

SQLite avec Mono

Linq-to-SQL

Dans MonoDevelop, on peut utiliser LINQ to SQL. Même en suivant la procédure de MonoDevelop sur Linq, lorsque vient le temps de générer la classe pour le DataContext, voilà ce qu'on peut obtenir :

MonoDevelop.Database.Sql.SqlMetalExecException: sqlmetal: Object reference not set to an instance of an object.

Pour palier à ce problème, on peut directement utiliser sqlmetal (de DbMetal) par le terminal (Mac OS X et Linux).

sqlmetal

Ceci est un exemple de l'utilisation de sqlmetal avec une base de données SQLite.

sqlmetal -d=bdqdatabase.db3 --provider=Sqlite -c="Data Source=./bdqdatabase.db3" --code=output.cs

L'utilitaire sqlmetal est censé mettre au pluriel les collections d'entités et mettre au singulier les entités elle-mêmes. Ce n'est pas le cas selon ce qu'on peut voir. Il est permis de tweaker un peu dans le code généré.

Renommer les entités

Changer les collections :

public Table<Books> Books
{
    get
    {
        return this.GetTable <Books>();
    }
}

devient :

public Table<Book> Books
{
    get
    {
        return this.GetTable <Book>();
    }
}

Changer les classes d'entités :

[Table(Name="main.books")]
public partial class Books : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged
{
//...//
public Books()
{
    this.OnCreated();
}

devient :

[Table(Name="main.books")]
public partial class Book : System.ComponentModel.INotifyPropertyChanging, System.ComponentModel.INotifyPropertyChanged
{
//...//
public Book()
{
    this.OnCreated();
}
Le gros problème avec cette pratique, c'est que si on régénère le fichier, tous les changements effectués manuellement seront perdus.

Utilisation

Création de la table

Créer une table dans une base de données SQLite semblable à celle-ci :

CREATE TABLE "books" (
    "id" INTEGER PRIMARY KEY,
    "style_id" INTEGER,
    "title" TEXT,
    "description" TEXT
);

Il ne faut pas ajout de modificateurs tel que AUTOINCREMENT ou NOT NULL à la clé primaire de la table, car des erreurs tels que

Abort due to constraint violation: books.id may not be NULL

peuvent survenir. Linq-to-SQL se charge d'autoincrémenter la clé primaire si elle est définie correctement.

Références

La classe utilisant Linq et le contexte doit avoir les références suivantes :

using System.Linq;
using System.Data;
using System.Data.Common;
using System.Data.SQLite;

Il faut ajouter une référence à System.Data.SQLite, qui est un DLL qui se trouve sur le site de System.Data.SQLite.

Exemple de code Linq-to-SQL

DbConnection cnn = new SQLiteConnection("DbLinqProvider=Sqlite;Data Source=books.db3");
BdqDataContext db = new BdqDataContext(cnn);
 
Books book = new Books();
book.Title = "Titre du livre";
book.Description = "Ici une description du livre...";
 
db.Books.InsertOnSubmit(book);
db.SubmitChanges();

Mono.Data.SqliteClient

using System;
 using System.Data;
 using Mono.Data.SqliteClient;
 
 public class Test
 {
    public static void Main(string[] args)
    {
       string connectionString = "URI=file:SqliteTest.db";
       IDbConnection dbcon;
       dbcon = (IDbConnection) new SqliteConnection(connectionString);
       dbcon.Open();
       IDbCommand dbcmd = dbcon.CreateCommand();
       // requires a table to be created named employee
       // with columns firstname and lastname
       // such as,
       //        CREATE TABLE employee (
       //           firstname varchar(32),
       //           lastname varchar(32));
       string sql =
          "SELECT firstname, lastname " +
          "FROM employee";
       dbcmd.CommandText = sql;
       IDataReader reader = dbcmd.ExecuteReader();
       while(reader.Read()) {
            string FirstName = reader.GetString (0);
            string LastName = reader.GetString (1);
            Console.WriteLine("Name: " +
                FirstName + " " + LastName);
       }
       // clean up
       reader.Close();
       reader = null;
       dbcmd.Dispose();
       dbcmd = null;
       dbcon.Close();
       dbcon = null;
    }
 }

Source : SQLite on mono-project.com

using System;
using System.IO;
using System.Data;  
using Mono.Data.Sqlite; 
/* ... */
        var documents = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
        string db = System.IO.Path.Combine (documents, "mydb.db3");
		//System.IO.Path.Combine
        bool exists = File.Exists (db);
        if (!exists)
            SqliteConnection.CreateFile (db);
        var conn = new SqliteConnection("Data Source=" + db);
        if (!exists) {
            var commands = new[] {
            "CREATE TABLE People (PersonID INTEGER NOT NULL, FirstName ntext, LastName ntext)",
            "INSERT INTO People (PersonID, FirstName, LastName) VALUES (1, 'First', 'Last')",
            "INSERT INTO People (PersonID, FirstName, LastName) VALUES (2, 'Dewey', 'Cheatem')",
            "INSERT INTO People (PersonID, FirstName, LastName) VALUES (3, 'And', 'How')",
            };
            foreach (var cmd in commands)
                using (var c = conn.CreateCommand()) {
                    c.CommandText = cmd;
                    c.CommandType = CommandType.Text;
                    conn.Open ();
                    c.ExecuteNonQuery ();
                    conn.Close ();
                }
        }

Source : http://monotouch.net/Documentation/System.Data

System.Data.SQLite

Create Table

(Le code ne fonctionne pas.)

SQLiteConnection connection = new SQLiteConnection("Data Source=sqldatabase.db");
connection.Open();
SQLiteCommand command = new SQLiteCommand(connection);
command.CommandText = "CREATE TABLE users (id integer primary key autoincrement, username varchar(32), password varchar(128))";
command.ExecuteNonQuery();
connection.Close();

Quick insert

      using (SQLiteTransaction mytransaction = myconnection.BeginTransaction())
      {
        using (SQLiteCommand mycommand = new SQLiteCommand(myconnection))
        {
          SQLiteParameter myparam = new SQLiteParameter();
          int n;
 
          mycommand.CommandText = "INSERT INTO [MyTable] ([MyId]) VALUES(?)";
          mycommand.Parameters.Add(myparam);
 
          for (n = 0; n < 100000; n ++)
          {
            myparam.Value = n + 1;
            mycommand.ExecuteNonQuery();
          }
        }
        mytransaction.Commit();
      } 

Source : SQLite.NET Help (CHM file)

Ressources