Как подключить SQLite в Xamarin-приложении?

Для работы с локальной базой данных в Xamarin-приложении часто используют SQLite — встраиваемую реляционную СУБД. Она не требует отдельного сервера, легко интегрируется и отлично подходит для хранения данных на устройстве пользователя. В Xamarin SQLite реализуется с помощью библиотеки sqlite-net-pcl, которая предоставляет простой ORM-интерфейс (Object-Relational Mapping) на C#.

1. Установка библиотеки SQLite

SQLite используется через библиотеку sqlite-net-pcl, которая является кроссплатформенной и работает на Android, iOS, Windows и Mac.

Шаги:

Через NuGet:

Установите пакет sqlite-net-pcl в общий проект (Shared или .NET Standard) и в каждый проект платформы (Android, iOS, UWP):

Install-Package sqlite-net-pcl

Или через интерфейс NuGet в Visual Studio:

  • ПКМ по проекту → Manage NuGet Packages → Browse → sqlite-net-pcl → Install.

2. Создание модели данных

Для взаимодействия с таблицами создаются классы-модели, где каждая модель представляет таблицу.

Пример модели:

using SQLite;
public class Person
{
\[PrimaryKey, AutoIncrement\]
public int Id { get; set; }
\[MaxLength(100)\]
public string Name { get; set; }
public int Age { get; set; }
}

Атрибуты SQLite:

  • [PrimaryKey] — указывает первичный ключ.

  • [AutoIncrement] — автоматическое увеличение ID.

  • [MaxLength(N)] — ограничение длины строки.

  • [Indexed] — создать индекс по полю.

3. Создание и настройка подключения к базе данных

SQLite использует файл базы данных, размещённый в локальной файловой системе устройства. Нужно определить путь к этому файлу и создать подключение.

Пример (в .NET Standard или Shared Code):

public static class DatabaseConstants
{
public const string DatabaseFilename = "MyApp.db3";
public const SQLite.SQLiteOpenFlags Flags =
SQLite.SQLiteOpenFlags.ReadWrite |
SQLite.SQLiteOpenFlags.Create |
SQLite.SQLiteOpenFlags.SharedCache;
public static string DatabasePath =>
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), DatabaseFilename);
}

4. Создание класса для работы с БД

Создаётся сервис или репозиторий, который инкапсулирует операции с базой.

Пример DatabaseService:

public class DatabaseService
{
private readonly SQLiteAsyncConnection \_database;
public DatabaseService()
{
\_database = new SQLiteAsyncConnection(DatabaseConstants.DatabasePath, DatabaseConstants.Flags);
\_database.CreateTableAsync<Person>().Wait(); // Создание таблицы при инициализации
}
public Task&lt;List<Person&gt;> GetPeopleAsync()
{
return \_database.Table&lt;Person&gt;().ToListAsync();
}
public Task&lt;Person&gt; GetPersonAsync(int id)
{
return \_database.Table&lt;Person&gt;().Where(p => p.Id == id).FirstOrDefaultAsync();
}
public Task&lt;int&gt; SavePersonAsync(Person person)
{
if (person.Id != 0)
{
return \_database.UpdateAsync(person);
}
else
{
return \_database.InsertAsync(person);
}
}
public Task&lt;int&gt; DeletePersonAsync(Person person)
{
return \_database.DeleteAsync(person);
}
}

5. Регистрация сервиса

Можно создать синглтон в App.xaml.cs или через Dependency Injection.

Пример в App.xaml.cs:

public static DatabaseService Database { get; private set; }
public App()
{
InitializeComponent();
Database = new DatabaseService();
MainPage = new NavigationPage(new MainPage());
}

6. Использование базы данных в ViewModel или Code-behind

Теперь можно использовать сервис в любом месте приложения для работы с данными.

Пример (Code-behind страницы):

protected override async void OnAppearing()
{
base.OnAppearing();
var people = await App.Database.GetPeopleAsync();
peopleListView.ItemsSource = people;
}

Пример добавления записи:

private async void OnAddClicked(object sender, EventArgs e)
{
var person = new Person { Name = "Алексей", Age = 30 };
await App.Database.SavePersonAsync(person);
}

7. Потокобезопасность и асинхронность

В Xamarin.Forms, особенно на Android, важно использовать асинхронные методы (SQLiteAsyncConnection) вместо синхронных (SQLiteConnection), чтобы избежать заморозки интерфейса и ANR (Application Not Responding).

Методы:

  • InsertAsync, UpdateAsync, DeleteAsync, QueryAsync, ExecuteAsync

  • CreateTableAsync<T>()

  • Table<T>()

8. Работа с несколькими таблицами

Создание дополнительных моделей:

public class Order
{
\[PrimaryKey, AutoIncrement\]
public int Id { get; set; }
public string Product { get; set; }
public int Quantity { get; set; }
}

В конструкторе DatabaseService:

_database.CreateTableAsync<Order>().Wait();

9. Сложные запросы и SQL

Кроме ORM-методов можно выполнять сырой SQL:

var result = await \_database.QueryAsync&lt;Person&gt;("SELECT \* FROM Person WHERE Age > ?", 25);

Также можно использовать ExecuteAsync для выполнения команд:

await \_database.ExecuteAsync("DELETE FROM Person WHERE Age < ?", 18);

10. Отладка SQLite на Android

  • Используйте adb shell и sqlite3 для подключения к базе на устройстве/эмуляторе.

  • Путь к файлу: /data/data/com.companyname.myapp/files/MyApp.db3

  • Можно использовать SQLite Viewer или переносить файл БД с устройства через ADB.

11. Обновление схемы базы данных

Если нужно изменить структуру таблицы (добавить поле, изменить тип), SQLite не поддерживает ALTER TABLE во всех формах. Возможные подходы:

  • Создать новую таблицу, перенести данные и удалить старую.

  • Использовать DropTableAsync и затем CreateTableAsync (с потерей данных).

  • Добавить миграции вручную или с помощью сторонних библиотек (например, SQLiteNetExtensions.Migrations).

12. Использование SQLiteNetExtensions (необязательно)

Если требуется поддержка отношений между таблицами (1:1, 1:N, N:M), можно использовать SQLiteNetExtensions.

Пример:

public class Author
{
\[PrimaryKey, AutoIncrement\]
public int Id { get; set; }
public string Name { get; set; }
\[OneToMany(CascadeOperations = CascadeOperation.All)\]
public List&lt;Book&gt; Books { get; set; }
}
public class Book
{
\[PrimaryKey, AutoIncrement\]
public int Id { get; set; }
public string Title { get; set; }
\[ForeignKey(typeof(Author))\]
public int AuthorId { get; set; }
}
await \_database.InsertWithChildrenAsync(author, true); // рекурсивная вставка

13. Хранение и шифрование базы (по желанию)

Для безопасного хранения данных можно использовать SQLCipher:

  • Установить пакет: SQLite.Net.SQLCipher

  • Задать ключ при подключении к базе

  • Это особенно важно при работе с конфиденциальной информацией.

Подключение SQLite к Xamarin-приложению позволяет создавать автономные, офлайн-ориентированные приложения с полной локальной базой данных. Это особенно полезно для заметок, контактов, заказов, чек-листов, форм и других видов контента, которые должны сохраняться на устройстве.