Использование 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:
В приведенном ниже коде показано, как выполнять простые операции SQLite и отображать результаты в виде текста в главном окне приложения.
Вам потребуется включить эти пространства имен:
using System;
using System.IO;
using Mono.Data.Sqlite;
В следующем примере кода показано все взаимодействие с базой данных:
- Создание файла базы данных
- Вставка некоторых данных
- Запрос данных
Эти операции обычно отображаются в нескольких местах в коде, например, вы можете создать файл базы данных и таблицы при первом запуске приложения и выполнять операции чтения и записи данных на отдельных экранах в приложении. В приведенном ниже примере сгруппированы в один метод для этого примера:
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
инструкции , или DELETE
INSERT
UPDATE
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
методов, возвращающих объект чтения или количество затронутых строк.