System.Data en Xamarin.iOS

Xamarin.iOS 8.10 agrega compatibilidad con System.Data, incluido el proveedor Mono.Data.Sqlite.dll de ADO.NET. La compatibilidad incluye la adición de los siguientes ensamblados:

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

Ejemplo

El siguiente programa crea una base de datos en Documents/mydb.db3 y, si la base de datos no existe anteriormente, se rellena con datos de ejemplo. A continuación, se consulta la base de datos, con la salida escrita en stderr.

Agregar referencias

En primer lugar, haga clic con el botón derecho en el nodo Referencias y elija Editar referencias... a continuación, seleccione System.Data y Mono.Data.Sqlite:

Adding new references

Código de ejemplo

El código siguiente muestra un ejemplo sencillo de creación de una tabla e inserción de filas mediante comandos SQL insertados:

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]);
    }
}

Importante

Como se mencionó en el ejemplo de código anterior, es un procedimiento incorrecto insertar cadenas en comandos SQL porque hace que el código sea vulnerable a la inyección de CÓDIGO SQL.

Uso de parámetros de comando

El código siguiente muestra cómo usar parámetros de comando para insertar texto escrito por el usuario de forma segura en la base de datos (incluso si el texto contiene caracteres SQL especiales como apóstrofo único):

// 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 ();
}

Falta de funcionalidad

Tanto a System.Data como a Mono.Data.Sqlite le faltan algunas funcionalidades.

System.Data

La funcionalidad que falta en System.Data.dll es:

Mono.Data.Sqlite

Mientras tanto, Mono.Data.Sqlite.dll no sufrió ningún cambio en el código fuente, pero en su lugar puede hospedarse en una serie de problemas en tiempo de ejecución, ya que Mono.Data.Sqlite.dll enlaza SQLite 3.5. iOS 8, mientras tanto, se distribuye con SQLite 3.8.5. Basta con decir que algunas cosas han cambiado entre las dos versiones.

La versión anterior de iOS se distribuye con las siguientes versiones de SQLite:

  • iOS 7: versión 3.7.13.
  • iOS 6: versión 3.7.13.
  • iOS 5: versión 3.7.7.
  • iOS 4: versión 3.6.22.

Los problemas más comunes parecen estar relacionados con la consulta de esquemas de base de datos, por ejemplo, determinar en tiempo de ejecución qué columnas existen en una tabla determinada, como Mono.Data.Sqlite.SqliteConnection.GetSchema (invalidar DbConnection.GetSchema y Mono.Data.Sqlite.SqliteDataReader.GetSchemaTable (invalidar DbDataReader.GetSchemaTable. En resumen, parece que es poco probable que funcione cualquier cosa que use DataTable.

Enlace de datos

El enlace de datos no se admite en este momento.