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
:
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:
- Cualquier cosa que requiera System.CodeDom (por ejemplo , System.Data.TypedDataSetGenerator )
- Compatibilidad con archivos de configuración XML (por ejemplo , System.Data.Common.DbProviderConfigurationHandler )
- System.Data.Common.DbProviderFactories (depende de la compatibilidad con archivos de configuración XML)
- System.Data.OleDb
- System.Data.Odbc
- La dependencia
System.EnterpriseServices.dll
se eliminó deSystem.Data.dll
, lo que da lugar a la eliminación del método SqlConnection.EnlistDistributedTransaction(ITransaction).
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.