Xamarin.iOS 中的 System.Data

Xamarin.iOS 8.10 添加了对system.Data(包括Mono.Data.Sqlite.dll ADO.NET 提供程序)的支持。 支持包括添加以下程序集

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

示例

以下程序在Documents/mydb.db3中创建数据库,如果数据库以前不存在,则使用示例数据填充该数据库。 然后查询数据库,并将输出写入stderr

添加引用

首先,右击“引用”节点,然后依次选择“编辑引用...”、“System.Data”和“Mono.Data.Sqlite

Adding new references

代码示例

以下代码演示了使用嵌入式 SQL 命令创建表和插入行的简单示例:

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

重要

如上面的代码示例中所述,在 SQL 命令中嵌入字符串是错误的做法,因为它会使代码容易受到SQL 注入的攻击。

使用命令参数

以下代码演示了如何使用命令参数将用户输入的文本安全地插入数据库中(即使文本包含单撇号等特殊的 SQL 字符):

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

缺少功能

System.DataMono.Data.Sqlite缺少一些功能。

System.Data

System.Data.dll中缺少的功能包括:

Mono.Data.Sqlite

同时,由于Mono.Data.Sqlite.dll绑定 SQLite 3.5, Mono.Data.Sqlite.dll没有源代码更改,但可能会托管许多运行时问题。 同时,iOS 8 附带 SQLite 3.8.5。 可以说,这两个版本之间发生了一些变化。

旧版 iOS 附带了以下版本的 SQLite:

  • iOS 7 - 版本 3.7.13。
  • iOS 6 - 版本 3.7.13。
  • iOS 5 - 版本 3.7.7。
  • iOS 4 - 版本 3.6.22。

最常见的问题似乎与数据库架构查询有关,例如在运行时确定给定表上存在哪些列,例如Mono.Data.Sqlite.SqliteConnection.GetSchema(替代DbConnection.GetSchema)和Mono.Data.Sqlite.SqliteDataReader.GetSchemaTable(替代DbDataReader.GetSchemaTable)。 简言之,使用DataTable的任何操作似乎都不太可能正常工作。

数据绑定

目前不支持数据绑定。