System.Data no Xamarin.iOS

O Xamarin.iOS 8.10 adiciona suporte para System.Data, incluindo o Mono.Data.Sqlite.dll provedor de ADO.NET. O suporte inclui a adição dos seguintes assemblies:

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

Exemplo

O programa a seguir cria um banco de dados no Documents/mydb.db3e, se o banco de dados não existir anteriormente, ele será preenchido com dados de exemplo. Em seguida, o banco de dados é consultado, com a saída gravada stderrem .

Adicionar referências

Primeiro, clique com o botão direito do mouse no nó Referências e escolha Editar Referências... em seguida, selecione System.Data e Mono.Data.Sqlite:

Adicionando novas referências

Exemplo de código

O código a seguir mostra um exemplo simples de criação de uma tabela e inserção de linhas usando comandos SQL inseridos:

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

Conforme mencionado no exemplo de código acima, é uma prática inadequada inserir cadeias de caracteres em comandos SQL porque torna seu código vulnerável à injeção de SQL.

Uso de parâmetros de comando

O código a seguir mostra como usar parâmetros de comando para inserir texto inserido pelo usuário com segurança no banco de dados (mesmo que o texto contenha caracteres SQL especiais, 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 ();
}

Funcionalidade ausente

System.Data e Mono.Data.Sqlite não têm algumas funcionalidades.

System.Data

A funcionalidade ausente de System.Data.dll consiste em:

Mono.Data.Sqlite

Enquanto isso, Mono.Data.Sqlite.dll não sofreu alterações no código-fonte, mas pode ser o host de vários problemas de runtime , já Mono.Data.Sqlite.dll que associa o SQLite 3.5. O iOS 8, entretanto, é fornecido com o SQLite 3.8.5. Basta dizer que algumas coisas mudaram entre as duas versões.

Versão mais antiga do iOS fornecida com as seguintes versões do SQLite:

  • iOS 7 – versão 3.7.13.
  • iOS 6 – versão 3.7.13.
  • iOS 5 – versão 3.7.7.
  • iOS 4 – versão 3.6.22.

Os problemas mais comuns parecem estar relacionados à consulta de esquema de banco de dados, por exemplo, determinar em runtime quais colunas existem em uma determinada tabela, como Mono.Data.Sqlite.SqliteConnection.GetSchema (substituindo DbConnection.GetSchema e Mono.Data.Sqlite.SqliteDataReader.GetSchemaTable (substituindo DbDataReader.GetSchemaTable). Em suma, parece que é improvável que qualquer coisa que use DataTable funcione.

Associação de dados

No momento, não há suporte para a Associação de Dados.