[Действие GitHub] [Отчет о покрытии кода]
Используйте один из этих пакетов:
Версия | Упаковка | Описание |
---|---|---|
sqlite-net-pcl | Стандартная библиотека .NET | |
sqlite-net-sqlcipher | С поддержкой шифрования | |
sqlite-net-static | Специальная версия, которая использует P/Invokes для предоставляемого платформой sqlite3. | |
sqlite-net-base | без пакета SQLitePCLRaw, чтобы вы могли выбрать собственного поставщика |
SQLite-net — это минимальная библиотека с открытым исходным кодом, позволяющая приложениям .NET, .NET Core и Mono хранить данные в базах данных SQLite 3. Первоначально он был разработан для работы с Xamarin.iOS, но с тех пор стал работать на всех платформах (Xamarin.*, .NET, UWP, Azure и т. д.).
SQLite-net был разработан как быстрый и удобный уровень базы данных. Его конструкция следует из следующих целей :
Очень легко интегрируется с существующими проектами и работает на всех платформах .NET.
Тонкая оболочка над SQLite, быстрая и эффективная. (Эта библиотека не должна быть узким местом производительности ваших запросов.)
Очень простые методы для безопасного выполнения операций и запросов CRUD (с использованием параметров) и для получения результатов этих запросов строго типизированным способом.
Работает с вашей моделью данных, не заставляя вас менять классы. (Содержит небольшой слой ORM, управляемый отражением.)
Установите sqlite-net-pcl из NuGet.
Важно! Вам потребуется добавить пакет NuGet как в проект библиотеки .NET Standard, так и в проект приложения, зависящего от платформы .
SQLite-net содержится в одном файле (я знаю, это так круто, правда?) и его легко добавить в ваш проект. Просто добавьте SQLite.cs в свой проект, и вы готовы приступить к созданию таблиц. Асинхронную реализацию можно найти в SQLiteAsync.cs.
Это проект с открытым исходным кодом, который приветствует вклады/предложения/сообщения об ошибках от тех, кто его использует. Если у вас есть идеи по улучшению библиотеки, опубликуйте вопрос здесь, на GitHub. Пожалуйста, ознакомьтесь с разделом «Как внести свой вклад».
Пожалуйста, обратитесь к Wiki для получения полной документации.
Библиотека содержит простые атрибуты, которые можно использовать для управления построением таблиц. В простой стандартной программе вы можете использовать:
public class Stock
{
[ PrimaryKey , AutoIncrement ]
public int Id { get ; set ; }
public string Symbol { get ; set ; }
}
public class Valuation
{
[ PrimaryKey , AutoIncrement ]
public int Id { get ; set ; }
[ Indexed ]
public int StockId { get ; set ; }
public DateTime Time { get ; set ; }
public decimal Price { get ; set ; }
[ Ignore ]
public string IgnoreField { get ; set ; }
}
После того как вы определили объекты в своей модели, у вас есть выбор API. Вы можете использовать «синхронный API», где вызовы блокируются по одному, или вы можете использовать «асинхронный API», где вызовы не блокируются. Возможно, вы захотите использовать асинхронный API для мобильных приложений, чтобы повысить скорость реагирования.
Оба API описаны в двух разделах ниже.
После того как вы определили свою сущность, вы можете автоматически генерировать таблицы в своей базе данных, вызвав CreateTable
:
// Get an absolute path to the database file
var databasePath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . MyDocuments ) , " MyData.db " ) ;
var db = new SQLiteConnection ( databasePath ) ;
db . CreateTable < Stock > ( ) ;
db . CreateTable < Valuation > ( ) ;
Вы можете вставлять строки в базу данных с помощью Insert
. Если таблица содержит автоматически увеличивающийся первичный ключ, то значение этого ключа будет доступно вам после вставки:
public static void AddStock ( SQLiteConnection db , string symbol ) {
var stock = new Stock ( ) {
Symbol = symbol
} ;
db . Insert ( stock ) ;
Console . WriteLine ( " {0} == {1} " , stock . Symbol , stock . Id ) ;
}
Аналогичные методы существуют для Update
и Delete
.
Самый простой способ запроса данных — использование метода Table
. Это может использовать предикаты для ограничения с помощью предложений WHERE и/или добавления предложений ORDER BY:
var query = db . Table < Stock > ( ) . Where ( v => v . Symbol . StartsWith ( " A " ) ) ;
foreach ( var stock in query )
Console . WriteLine ( " Stock: " + stock . Symbol ) ;
Вы также можете запросить базу данных на низком уровне, используя метод Query
:
public static IEnumerable < Valuation > QueryValuations ( SQLiteConnection db , Stock stock ) {
return db . Query < Valuation > ( " select * from Valuation where StockId = ? " , stock . Id ) ;
}
Общий параметр метода Query
указывает тип объекта, который необходимо создать для каждой строки. Это может быть один из ваших классов таблиц или любой другой класс, общедоступные свойства которого соответствуют столбцу, возвращаемому запросом. Например, мы могли бы переписать приведенный выше запрос так:
public class Val
{
public decimal Money { get ; set ; }
public DateTime Date { get ; set ; }
}
public static IEnumerable < Val > QueryVals ( SQLiteConnection db , Stock stock ) {
return db . Query < Val > ( " select " Price " as " Money " , " Time " as " Date " from Valuation where StockId = ? " , stock . Id ) ;
}
Вы можете выполнять низкоуровневые обновления базы данных с помощью метода Execute
.
Асинхронная библиотека использует библиотеку параллельных задач (TPL). Таким образом, вам подойдет обычное использование объектов Task
и ключевых слов async
и await
.
После того как вы определили свою сущность, вы можете автоматически генерировать таблицы, вызвав CreateTableAsync
:
// Get an absolute path to the database file
var databasePath = Path . Combine ( Environment . GetFolderPath ( Environment . SpecialFolder . MyDocuments ) , " MyData.db " ) ;
var db = new SQLiteAsyncConnection ( databasePath ) ;
await db . CreateTableAsync < Stock > ( ) ;
Console . WriteLine ( " Table created! " ) ;
Вы можете вставлять строки в базу данных с помощью Insert
. Если таблица содержит автоматически увеличивающийся первичный ключ, то значение этого ключа будет доступно вам после вставки:
var stock = new Stock ( )
{
Symbol = " AAPL "
} ;
await db . InsertAsync ( stock ) ;
Console . WriteLine ( " Auto stock id: {0} " , stock . Id ) ;
Аналогичные методы существуют для UpdateAsync
и DeleteAsync
.
Запрос данных проще всего выполнить с помощью метода Table
. Это вернет экземпляр AsyncTableQuery
обратно, после чего вы можете добавить предикаты для ограничения с помощью предложений WHERE и/или добавления ORDER BY. База данных физически не затрагивается до тех пор, пока не будет вызван один из специальных методов извлечения — ToListAsync
, FirstAsync
или FirstOrDefaultAsync
.
var query = db . Table < Stock > ( ) . Where ( s => s . Symbol . StartsWith ( " A " ) ) ;
var result = await query . ToListAsync ( ) ;
foreach ( var s in result )
Console . WriteLine ( " Stock: " + s . Symbol ) ;
Существует ряд низкоуровневых методов. Вы также можете запросить базу данных напрямую с помощью метода QueryAsync
. Помимо операций изменения, предоставляемых InsertAsync
и т. д., вы можете использовать методы ExecuteAsync
для изменения наборов данных непосредственно в базе данных.
Еще один полезный метод — ExecuteScalarAsync
. Это позволяет вам легко возвращать скалярное значение из базы данных:
var count = await db . ExecuteScalarAsync < int > ( " select count(*) from Stock " ) ;
Console . WriteLine ( string . Format ( " Found '{0}' stock items. " , count ) ) ;
sqlite-net обычно используется в качестве легкого ORM (объектно-реляционного преобразователя) с использованием методов CreateTable
и Table
. Однако вы также можете использовать его как удобный способ выполнения запросов вручную.
Вот пример создания таблицы, вставки в нее (с помощью параметризованной команды) и запроса к ней без использования функций ORM.
db . Execute ( " create table Stock(Symbol varchar(100) not null) " ) ;
db . Execute ( " insert into Stock(Symbol) values (?) " , " MSFT " ) ;
var stocks = db . Query < Stock > ( " select * from Stock " ) ;
Вы можете использовать зашифрованную базу данных с помощью пакета NuGet sqlite-net-sqlcipher.
Ключ базы данных устанавливается в SqliteConnectionString
передаваемом конструктору соединения:
var options = new SQLiteConnectionString ( databasePath , true ,
key : " password " ) ;
var encryptedDb = new SQLiteAsyncConnection ( options ) ;
Если вам нужно установить прагмы для управления шифрованием, действия можно передать в строку подключения:
var options2 = new SQLiteConnectionString ( databasePath , true ,
key : " password " ,
preKeyAction : db => db . Execute ( " PRAGMA cipher_default_use_hmac = OFF; " ) ,
postKeyAction : db => db . Execute ( " PRAGMA kdf_iter = 128000; " ) ) ;
var encryptedDb2 = new SQLiteAsyncConnection ( options2 ) ;
Спасибо сообществу .NET за поддержку этого проекта, а также всем участникам, которые помогли сделать его успешным.
Также спасибо Тирзе ван Дейку (@tirzavdijk) за великолепный логотип!