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.db3
e, 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 stderr
em .
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
:
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:
- Qualquer coisa que exija System.CodeDom (por exemplo, System.Data.TypedDataSetGenerator )
- Suporte ao arquivo de configuração XML (por exemplo, System.Data.Common.DbProviderConfigurationHandler )
- System.Data.Common.DbProviderFactories (depende do suporte ao arquivo de configuração XML)
- System.Data.OleDb
- System.Data.Odbc
- A
System.EnterpriseServices.dll
dependência foi removida deSystem.Data.dll
, resultando na remoção do método SqlConnection.EnlistDistributedTransaction(ITransaction).
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.