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

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

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

Чтобы использовать sqLite через ADO.NET необходимо добавить System.Data и Mono.Data.Sqlite ссылки на проект Android, как показано ниже:

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

О Mono.Data.Sqlite

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

Создание пустой базы данных — вызов CreateFile метода с допустимым (т. е. возможностью записи) пути к файлу. Необходимо проверка, существует ли файл перед вызовом этого метода, в противном случае новая (пустая) база данных будет создана в верхней части старого, а данные в старом файле будут потеряны. Mono.Data.Sqlite.SqliteConnection.CreateFile (dbPath); Переменная dbPath должна быть определена в соответствии с правилами, описанными ранее в этом документе.

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

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

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

Создание и выполнение команды базы данных. После подключения к нему можно выполнить произвольные команды 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 для этого документа выглядит следующим образом при запуске в Android:

Android 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инструкции , или DELETEINSERTUPDATESELECT инструкции, которые вам нравится. Вы можете прочитать о командах 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 методов, возвращающих объект чтения или количество затронутых строк.