[GitHub 操作] [代码覆盖率报告]
使用以下包之一:
版本 | 包裹 | 描述 |
---|---|---|
sqlite-net-pcl | .NET 标准库 | |
sqlite-net-sqlcipher | 具有加密支持 | |
sqlite 网络静态 | 使用P/Invokes平台提供的sqlite3的特殊版本 | |
sqlite-网络基础 | 没有 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。您可以使用“同步 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通常使用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) 提供的出色徽标!