System.Data dans Xamarin.iOS

Xamarin.iOS 8.10 ajoute la prise en charge de System.Data, y compris le Mono.Data.Sqlite.dll fournisseur de ADO.NET. La prise en charge inclut l’ajout des assemblys suivants :

  • System.Data.dll
  • System.Data.Service.Client.dll
  • System.Transactions.dll
  • Mono.Data.Tds.dll
  • Mono.Data.Sqlite.dll

Exemple

Le programme suivant crée une base de données dans Documents/mydb.db3, et si la base de données n’existe pas précédemment, elle est remplie avec des exemples de données. La base de données est ensuite interrogée, avec la sortie écrite dans stderr.

Ajouter des références

Tout d’abord, cliquez avec le bouton droit sur le nœud Références et choisissez Modifier les références... puis sélectionnez System.Data et Mono.Data.Sqlite:

Ajout de nouvelles références

Exemple de code

Le code suivant montre un exemple simple de création d’une table et d’insertion de lignes à l’aide de commandes SQL incorporées :

using System;
using System.Data;
using System.IO;
using Mono.Data.Sqlite;

class Demo {
    static void Main (string [] args)
    {
        var connection = GetConnection ();
        using (var cmd = connection.CreateCommand ()) {
            connection.Open ();
            cmd.CommandText = "SELECT * FROM People";
            using (var reader = cmd.ExecuteReader ()) {
                while (reader.Read ()) {
                    Console.Error.Write ("(Row ");
                    Write (reader, 0);
                    for (nint i = 1; i < reader.FieldCount; ++i) {
                        Console.Error.Write(" ");
                        Write (reader, i);
                    }
                    Console.Error.WriteLine(")");
                }
            }
            connection.Close ();
        }
    }

    static SqliteConnection GetConnection()
    {
        var documents = Environment.GetFolderPath (
                Environment.SpecialFolder.Personal);
        string db = Path.Combine (documents, "mydb.db3");
        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)",
            // WARNING: never insert user-entered data with embedded parameter values
            "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')",
            };
            conn.Open ();
            foreach (var cmd in commands) {
                using (var c = conn.CreateCommand()) {
                    c.CommandText = cmd;
                    c.CommandType = CommandType.Text;
                    c.ExecuteNonQuery ();
                }
            }
            conn.Close ();
        }
        return conn;
    }

    static void Write(SqliteDataReader reader, int index)
    {
        Console.Error.Write("({0} '{1}')",
                reader.GetName(index),
                reader [index]);
    }
}

Important

Comme mentionné dans l’exemple de code ci-dessus, il est mal pratique d’incorporer des chaînes dans des commandes SQL, car cela rend votre code vulnérable à l’injection SQL.

Utilisation des paramètres de commande

Le code suivant montre comment utiliser des paramètres de commande pour insérer du texte entré par l’utilisateur en toute sécurité dans la base de données (même si le texte contient des caractères SQL spéciaux comme une apostrophe unique) :

// user input from Textbox control
var fname = fnameTextbox.Text;
var lname = lnameTextbox.Text;
// use command parameters to safely insert into database
using (var addCmd = conn.CreateCommand ()) {
    addCmd.CommandText = "INSERT INTO [People] (PersonID, FirstName, LastName) VALUES (@COL1, @COL2, @COL3)";
    addCmd.CommandType = System.Data.CommandType.Text;
    addCmd.AddParameterWithValue ("@COL1", 1);
    addCmd.AddParameterWithValue ("@COL2", fname);
    addCmd.AddParameterWithValue ("@COL3", lname);
    addCmd.ExecuteNonQuery ();
}

Fonctionnalité manquante

System.Data et Mono.Data.Sqlite ne disposent pas de fonctionnalités.

System.Data

Les fonctionnalités manquantes dans System.Data.dll sont les suivantes :

Mono.Data.Sqlite

Pendant ce temps, Mono.Data.Sqlite.dll n’a subi aucune modification du code source, mais peut être l’hôte d’un certain nombre de problèmes d’exécution , car Mono.Data.Sqlite.dll lie SQLite 3.5. iOS 8, quant à lui, est fourni avec SQLite 3.8.5. Il suffit de dire que certaines choses ont changé entre les deux versions.

La version antérieure d’iOS est fournie avec les versions suivantes de SQLite :

  • iOS 7 - version 3.7.13.
  • iOS 6 - version 3.7.13.
  • iOS 5 - version 3.7.7.
  • iOS 4 - version 3.6.22.

Les problèmes les plus courants semblent être liés à l’interrogation de schémas de base de données, par exemple déterminer au moment de l’exécution quelles colonnes existent sur une table donnée, par Mono.Data.Sqlite.SqliteConnection.GetSchema exemple (remplacer DbConnection.GetSchema et Mono.Data.Sqlite.SqliteDataReader.GetSchemaTable (remplacer DbDataReader.GetSchemaTable). En bref, il semble que tout ce qui utilise DataTable soit peu susceptible de fonctionner.

Liaison de données

La liaison de données n’est pas prise en charge pour l’instant.