Поделиться через


Использование ADO.NET с Xamarin.iOS

Xamarin имеет встроенную поддержку базы данных SQLite, доступной в iOS, доступной с помощью знакомого ADO. Синтаксис, похожий на NET. Использование этих API требует написания инструкций SQL, обрабатываемых SQLite, таких как CREATE TABLEоператоры INSERT и SELECT инструкции.

Ссылки на сборки

Чтобы использовать sqLite через ADO.NET необходимо добавить System.Data и Mono.Data.Sqlite ссылки на проект iOS, как показано здесь (для примеров в Visual Studio для Mac и Visual Studio):

Щелкните правой кнопкой мыши ссылки > на изменения... Затем выберите необходимые сборки.

О Mono.Data.Sqlite

Мы будем использовать Mono.Data.Sqlite.SqliteConnection класс для создания пустого файла базы данных, а затем для создания экземпляров SqliteCommand объектов, которые можно использовать для выполнения инструкций SQL в базе данных.

  1. Создание пустой базы данных — вызов CreateFile метода допустимым (т. е. путь к файлу, который можно записать). Необходимо проверка, существует ли файл перед вызовом этого метода, в противном случае новая (пустая) база данных будет создана в верхней части старого, а данные в старом файле будут потеряны:

    Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath);

    Примечание.

    Переменная dbPath должна быть определена в соответствии с правилами, описанными ранее в этом документе.

  2. Создание базы данных Подключение. После создания файла базы данных SQLite можно создать объект подключения для доступа к данным. Соединение создается с помощью строка подключения, которая имеет формуData Source=file_path, как показано ниже:

    var connection = new SqliteConnection ("Data Source=" + dbPath);
    connection.Open();
    // do stuff
    connection.Close();
    

    Как упоминание ранее, подключение никогда не следует повторно использовать в разных потоках. Если вы сомневаетесь, создайте подключение по мере необходимости и закройте его по завершении; но помните, что делать это чаще, чем требуется тоже.

  3. Создание и выполнение команды базы данных. После подключения к нему можно выполнить произвольные команды SQL. В приведенном ниже коде показана инструкция CREATE TABLE, выполняемая.

    using (var command = connection.CreateCommand ()) {
        command.CommandText = "CREATE TABLE [Items] ([_id] int, [Symbol] ntext, [Name] ntext);";
        var rowcount = command.ExecuteNonQuery ();
    }
    

При выполнении SQL непосредственно в базе данных следует принять обычные меры предосторожности, чтобы не делать недопустимые запросы, например пытаться создать таблицу, которая уже существует. Следите за структурой базы данных, чтобы не вызывать sqliteException, например "Таблица ошибок SQLite [Элементы] уже существует.

Базовый доступ к данным

Пример кода DataAccess_Basic для этого документа выглядит следующим образом при запуске в iOS:

iOS ADO.NET sample

В приведенном ниже коде показано, как выполнять простые операции SQLite и отображать результаты в виде текста в главном окне приложения.

Вам потребуется включить эти пространства имен:

using System;
using System.IO;
using Mono.Data.Sqlite;

В следующем примере кода показано все взаимодействие с базой данных:

  1. Создание файла базы данных
  2. Вставка некоторых данных
  3. Запрос данных

Эти операции обычно отображаются в нескольких местах в коде, например, вы можете создать файл базы данных и таблицы при первом запуске приложения и выполнять операции чтения и записи данных на отдельных экранах в приложении. В приведенном ниже примере сгруппированы в один метод для этого примера:

public static SqliteConnection connection;
public static string DoSomeDataAccess ()
{
    // determine the path for the database file
    string dbPath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal),
        "adodemo.db3");

    bool exists = File.Exists (dbPath);

    if (!exists) {
        Console.WriteLine("Creating database");
        // Need to create the database before seeding it with some data
        Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath);
        connection = new SqliteConnection ("Data Source=" + dbPath);

        var commands = new[] {
            "CREATE TABLE [Items] (_id ntext, Symbol ntext);",
            "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('1', 'AAPL')",
            "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('2', 'GOOG')",
            "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('3', 'MSFT')"
        };
        // Open the database connection and create table with data
        connection.Open ();
        foreach (var command in commands) {
            using (var c = connection.CreateCommand ()) {
                c.CommandText = command;
                var rowcount = c.ExecuteNonQuery ();
                Console.WriteLine("\tExecuted " + command);
            }
        }
    } else {
        Console.WriteLine("Database already exists");
        // Open connection to existing database file
        connection = new SqliteConnection ("Data Source=" + dbPath);
        connection.Open ();
    }

    // query the database to prove data was inserted!
    using (var contents = connection.CreateCommand ()) {
        contents.CommandText = "SELECT [_id], [Symbol] from [Items]";
        var r = contents.ExecuteReader ();
        Console.WriteLine("Reading data");
        while (r.Read ())
            Console.WriteLine("\tKey={0}; Value={1}",
                              r ["_id"].ToString (),
                              r ["Symbol"].ToString ());
    }
    connection.Close ();
}

Более сложные запросы

Так как SQLite позволяет выполнять произвольные команды SQL для данных, вы можете выполнять любые инструкции CREATE, INSERT, UPDATE, DELETE или SELECT. Вы можете прочитать о командах SQL, поддерживаемых SQLite, на веб-сайте Sqlite. Инструкции SQL выполняются с помощью одного из трех методов в объекте SqliteCommand:

  • ExecuteNonQuery — обычно используется для создания таблицы или вставки данных. Возвращаемое значение для некоторых операций — это количество затронутых строк, в противном случае — значение -1.
  • ExecuteReader — используется при возврате SqlDataReader коллекции строк в виде.
  • ExecuteScalar — извлекает одно значение (например, агрегат).

EXECUTENONQUERY

Инструкции INSERT, UPDATE и DELETE возвращают количество затронутых строк. Все остальные инструкции SQL возвращают -1.

using (var c = connection.CreateCommand ()) {
    c.CommandText = "INSERT INTO [Items] ([_id], [Symbol]) VALUES ('1', 'APPL')";
    var rowcount = c.ExecuteNonQuery (); // rowcount will be 1
}

EXECUTEREADER

В следующем методе показано предложение WHERE в инструкции SELECT. Так как код создается полный оператор SQL, он должен заботиться о том, чтобы экранировать зарезервированные символы, такие как кавычки (') вокруг строк.

public static string MoreComplexQuery ()
{
    var output = "";
    output += "\nComplex query example: ";
    string dbPath = Path.Combine (
        Environment.GetFolderPath (Environment.SpecialFolder.Personal), "ormdemo.db3");

    connection = new SqliteConnection ("Data Source=" + dbPath);
    connection.Open ();
    using (var contents = connection.CreateCommand ()) {
        contents.CommandText = "SELECT * FROM [Items] WHERE Symbol = 'MSFT'";
        var r = contents.ExecuteReader ();
        output += "\nReading data";
        while (r.Read ())
            output += String.Format ("\n\tKey={0}; Value={1}",
                    r ["_id"].ToString (),
                    r ["Symbol"].ToString ());
    }
    connection.Close ();

    return output;
}

Метод ExecuteReader возвращает объект SqliteDataReader. Помимо метода Read, показанного в примере, к другим полезным свойствам относятся:

  • RowsAffected — количество строк, затронутых запросом.
  • HasRows — возвращаются ли какие-либо строки.

EXECUTESCALAR

Используйте это для инструкций SELECT, возвращающих одно значение (например, агрегат).

using (var contents = connection.CreateCommand ()) {
    contents.CommandText = "SELECT COUNT(*) FROM [Items] WHERE Symbol <> 'MSFT'";
    var i = contents.ExecuteScalar ();
}

Тип ExecuteScalar возвращаемого object метода — результат должен быть приведен в зависимости от запроса базы данных. Результатом может быть целое число из запроса COUNT или строки из одного запроса SELECT столбца. Обратите внимание, что это отличается от других методов Execute, возвращающих объект чтения или количество затронутых строк.

Microsoft.Data.Sqlite

Существует другая библиотека Microsoft.Data.Sqlite, которая может быть установлена из NuGet, которая функционально эквивалентна Mono.Data.Sqlite и разрешает те же типы запросов.

Существует сравнение между двумя библиотеками и некоторыми подробными сведениями о Xamarin. Наиболее важным для приложений Xamarin.iOS необходимо включить вызов инициализации:

// required for Xamarin.iOS
SQLitePCL.Batteries_V2.Init();