Как подключить 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<List<Person>> GetPeopleAsync()
{
return \_database.Table<Person>().ToListAsync();
}
public Task<Person> GetPersonAsync(int id)
{
return \_database.Table<Person>().Where(p => p.Id == id).FirstOrDefaultAsync();
}
public Task<int> SavePersonAsync(Person person)
{
if (person.Id != 0)
{
return \_database.UpdateAsync(person);
}
else
{
return \_database.InsertAsync(person);
}
}
public Task<int> 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<Person>("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<Book> 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-приложению позволяет создавать автономные, офлайн-ориентированные приложения с полной локальной базой данных. Это особенно полезно для заметок, контактов, заказов, чек-листов, форм и других видов контента, которые должны сохраняться на устройстве.