[GitHubアクション] [コードカバレッジレポート]
次のパッケージのいずれかを使用します。
バージョン | パッケージ | 説明 |
---|---|---|
sqlite-net-pcl | .NET標準ライブラリ | |
sqlite-net-sqlcipher | 暗号化サポートあり | |
sqlite-net-static | プラットフォームが提供する sqlite3 に対して P/Invoke を使用する特別なバージョン | |
sqlite-net-base | SQLitePCLRaw バンドルがないため、独自のプロバイダーを選択できます |
SQLite-net は、.NET、.NET Core、および Mono アプリケーションが SQLite 3 データベースにデータを保存できるようにするオープン ソースの最小限のライブラリです。最初は Xamarin.iOS で動作するように設計されましたが、その後、すべてのプラットフォーム (Xamarin.*、.NET、UWP、Azure など) で動作するように成長しました。
SQLite-net は、迅速で便利なデータベース層として設計されました。その設計は次の目標に従っています。
既存のプロジェクトとの統合が非常に簡単で、すべての .NET プラットフォームで実行できます。
高速かつ効率的な SQLite 上の薄いラッパー。 (このライブラリがクエリのパフォーマンスのボトルネックになってはいけません。)
CRUD 操作とクエリを (パラメーターを使用して) 安全に実行し、厳密に型指定された方法でそれらのクエリの結果を取得するための非常に単純なメソッド。
クラスの変更を強制することなく、データ モデルを操作できます。 (小さな反射駆動型 ORM レイヤーが含まれています。)
NuGet から sqlite-net-pcl をインストールします。
重要: NuGet パッケージを.NET Standard ライブラリ プロジェクトとプラットフォーム依存アプリ プロジェクトの両方に追加する必要があります。
SQLite-net はすべて 1 つのファイルに含まれており (とてもクールですよね?)、プロジェクトに簡単に追加できます。 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 を選択できるようになります。呼び出しが一度に 1 つずつブロックされる「同期 API」を使用することも、呼び出しがブロックされない「非同期 API」を使用することもできます。応答性を高めるために、モバイル アプリケーションに非同期 API を使用することもできます。
両方の API については、以下の 2 つのセクションで説明します。
エンティティを定義したら、 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
メソッドのジェネリック パラメーターは、各行に作成するオブジェクトのタイプを指定します。これは、テーブル クラスの 1 つ、またはクエリによって返された列と一致するパブリック プロパティを持つ他のクラスです。たとえば、上記のクエリを次のように書き直すことができます。
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
メソッドを発行してデータベース内のデータ セットを直接変更できます。
もう 1 つの便利なメソッドはExecuteScalarAsync
です。これにより、データベースからスカラー値を簡単に返すことができます。
var count = await db . ExecuteScalarAsync < int > ( " select count(*) from Stock " ) ;
Console . WriteLine ( string . Format ( " Found '{0}' stock items. " , count ) ) ;
sqlite-net は通常、 CreateTable
メソッドとTable
メソッドを使用して軽量 ORM (オブジェクト リレーショナル マッパー) として使用されます。ただし、クエリを手動で実行する便利な方法として使用することもできます。
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 " ) ;
sqlite-net-sqlcipher NuGet パッケージを使用すると、暗号化されたデータベースを使用できます。
データベース キーは、接続コンストラクターに渡される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 コミュニティに感謝します。また、このプロジェクトを素晴らしいものにするために協力してくれたすべての貢献者に感謝します。
素晴らしいロゴを提供してくれた Tirza van Dijk (@tirzavdijk) にも感謝します。