SQLite 已经成为小型数据库的王者,成为构建桌面程序、小型 Web 应用等必不可少的工具。给广大 .NETer 推荐一款 .NET 下的 SQLite 包装库 SQLite-net,非常好用,性能也很棒。
支持加密
加密一直是 SQLite 的一个重要掣肘,SQLite-net 可以通过 sqlite-net-sqlcipher 支持数据库加密,让你无需再为加密的问题犯愁。
var options = new SQLiteConnectionString(databasePath, true,key: "password");
var db = new SQLiteAsyncConnection(options);
简单易用
使用简单的类属性和特性定义表结构,提供了内置的 ORM 支持 和 Linq 查询语法,写起来自然流畅,丝滑无比。
public class Student
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
}
// 创建数据库
var db = new SQLiteConnection(databasePath);
db.CreateTable<Student>();
// 插入
var user = new User() { Name = "张三" };
db.Insert(user);
// 查询
var users = db.Table<User>().Where(u => v.Name.StartsWith("张")).ToList();
也可以直接使用 SQL 执行命令和查询,提高性能,增加灵活性。
db.Execute ("insert into User(Name) values (?)", "李四");
db.Query<User> ("select * from User where Id = ?", 3);
异步支持
所有的 API 都有异步版本,帮助你提高应用的性能。
await db.CreateTableAsync<User>();
await db.InsertAsync(user);
await db.Table<User>().Where(u => v.Name.StartsWith("张")).ToListAsync();
await db.ExecuteScalarAsync<int>("select count(*) from User");
总之,很棒,强烈推荐。项目地址:
https://github.com/praeclarum/sqlite-net
使用以下软件包之一:
版本 | 包裹 | 描述 |
---|---|---|
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 层。)
NuGet 安装
从 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; }
}
一旦您在模型中定义了对象,您就可以选择 API。您可以使用调用一次阻塞一个的“同步 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
您可以使用该方法执行数据库的低级别更新。
异步API
异步库使用任务并行库 (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
除了etc提供的更改操作之外,您还可以发出ExecuteAsync
直接在数据库中更改数据集的方法。
另一个有用的方法是ExecuteScalarAsync
。这使您可以轻松地从数据库返回标量值:
var count = await db.ExecuteScalarAsync<int>("select count(*) from Stock");
Console.WriteLine(string.Format("Found '{0}' stock items.", count));
手动 SQL
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");
使用 SQLCipher
您可以通过使用sqlite-net-sqlcipher NuGet 包来使用加密数据库。
数据库键在SqliteConnectionString
传递给连接构造函数时设置:
var options = new SQLiteConnectionString(databasePath, true,
key: "password");
var encryptedDb = new SQLiteAsyncConnection(options);
如果您需要设置 pragmas 来控制加密,可以将操作传递给连接字符串:
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) 提供的精美徽标!
标签:SQLite,db,超高,net,var,NET,public,stock From: https://www.cnblogs.com/guangzhiruijie/p/17027454.html