Fast Framework
專案地址 https://gitee.com/China-Mr-zhong/Fast.Framework
Author Mr-zhong
Wechat 850856667
Email 850856667@qq.com
QQ群 693979005
一、前言
1.為了實現快速開發,省去編寫大量Sql時間,更好的物件導向程式設計由此誕生了 Fast Framework
2.Fast Framework 是一個基於NET6.0 封裝的輕量級 ORM 框架 支援資料庫 SqlServer Oracle MySql PostgreSql Sqlite 由於底層使用System.Data.Common 抽象類封裝 理論支援所有Ado.Net 實現的類庫,差異部分可能需要額外處理。
3.框架 優點: 體積小 流暢API 使用更加簡單 效能高 缺點:不具備有自動建庫建表遷移等複雜的功能 由於不同資料庫差異較大 實現較為複雜 所以暫時不考慮實現
二、專案明細 (字尾為Test均為測試專案)
- Fast.Framework
- Fast.Framework.CustomAttribute
- Fast.Framework.Extensions
- Fast.Framework.Interfaces
- Fast.Framework.Logging
- Fast.Framework.Models
- Fast.Framework.Utils
三、快速入門
-
手動建立
var options = new DefaultDbOptions() //資料選項
{
DbType = DbType.MySQL,
ProviderName = "MySqlConnector",
FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout =30;AllowLoadLocalInfile=True;"
};
var ado = new Ado<DefaultDbOptions>(options);//原生Ado
var db = new DbContext<DefaultDbOptions>(ado);//資料庫上下文
-
依賴注入
var builder = WebApplication.CreateBuilder(args);
// 正式專案請用配置檔案注入,為了測試方便直接引用實現類庫
builder.Services.AddScoped<IAdo<DefaultDbOptions>, Ado<DefaultDbOptions>>();
builder.Services.AddScoped<IDbContext<DefaultDbOptions>, DbContext<DefaultDbOptions>>();
-
載入Json配置檔案
builder.Services.Configure<DefaultDbOptions>(configuration.GetSection("DbFactory:MySqlDb"));
-
Json 格式
"DbFactory": {
"MySQLDb": {
"DbType": "MySQL",
"ProviderName": "MySqlConnector",
"FactoryName": "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
"ConnectionStrings": "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout =30;"
},
"SQLServerDb": {
"DbType": "SQLServer",
"ProviderName": "System.Data.SqlClient",
"FactoryName": "System.Data.SqlClient.SqlClientFactory,System.Data",
"ConnectionStrings": "server=localhost;database=Test;user=sa;pwd=123456789;min pool size=3;max pool size=100;connect timeout =30;"
},
"OracleDb": {
"DbType": "Oracle",
"ProviderName": "Oracle.ManagedDataAccess.Client",
"FactoryName": "Oracle.ManagedDataAccess.Client.OracleClientFactory,Oracle.ManagedDataAccess",
"ConnectionStrings": "data source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=ORCL)));user id=system;password=Oracle2022;min pool size=3;max pool size=100;connect timeout =30;"
},
"PostgreSQLDb": {
"DbType": "PostgreSQL",
"ProviderName": "Npgsql",
"FactoryName": "Npgsql.NpgsqlFactory,Npgsql",
"ConnectionStrings": "host=localhost;database=test;userid=postgres;pwd=123456789;port=5432;"
},
"SQLiteDb": {
"DbType": "SQLite",
"ProviderName": "System.Data.SQLite",
"FactoryName": "System.Data.SQLite.SQLiteFactory,System.Data.SQLite",
"ConnectionStrings": "data source=mysqlite.db;pooling=true;"
}
}
-
Controller 構造方法注入已註冊的DbContext物件
namespace Fast.Framework.Web.Test.Controllers
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ProductController : ControllerBase
{
/// <summary>
/// 資料庫
/// </summary>
private readonly IDbContext<DefaultDbOptions> db;
/// <summary>
/// 日誌
/// </summary>
private readonly ILogger<ProductController> logger;
/// <summary>
/// 構造方法
/// </summary>
/// <param name="db"></param>
public ProductController(ILogger<ProductController> logger, IDbContext<DefaultDbOptions> db)
{
this.db = db;
this.logger = logger;
}
}
}
-
示例
#region 增 刪 改
//實體物件插入
{
var result = await db.Insert(new ProductModel() { ProductCode = "1001", ProductName = "測試產品1" }).ExecuteAsync();
Console.WriteLine(result);
}
//實體物件插入並返回自增ID 僅支援 SQLServer Mysql Sqlite
{
var result = await db.Insert(new ProductModel() { ProductCode = "1001", ProductName = "測試產品1" }).ExecuteReturnIdentityAsync();
Console.WriteLine(result);
}
//實體物件列表插入 列表插入不支援批量返回自增ID
{
var list = new List<ProductModel>();
list.Add(new ProductModel() { ProductCode = "1001", ProductName = "測試產品1" });
list.Add(new ProductModel() { ProductCode = "1002", ProductName = "測試產品2" });
var result = await db.Insert(list).ExecuteAsync();
Console.WriteLine(result);
}
//匿名物件插入 必須使用 As 方法顯示指定表名稱
{
var result = db.Insert(new { ProductCode = "1001", ProductName = "測試產品1" }).As("Product").ExecuteAsync();
Console.WriteLine(result);
}
//匿名物件列表插入 必須使用As 顯示指定表名稱
{
var list = new List<object>();
list.Add(new { ProductCode = "1001", ProductName = "測試產品1" });
list.Add(new { ProductCode = "1002", ProductName = "測試產品2" });
var result = await db.Insert(list).As("Product").ExecuteAsync();
Console.WriteLine(result);
}
//實體無條件刪除
{
var result = await db.Delete<ProductModel>().ExecuteAsync();
Console.WriteLine(result);
}
//實體條件刪除
{
var result = await db.Delete<ProductModel>().Where(w => w.ProductId == 1).ExecuteAsync();
Console.WriteLine(result);
}
//父類物件刪除
{
var result = db.Delete<object>().As("Product").ExecuteAsync();
Console.WriteLine(result);
}
//匿名物件條件刪除
{
var obj = new { ProductCode = "測試" };
var result = await db.Delete(obj).Where(w => w.ProductCode == obj.ProductCode).As("Product").ExecuteAsync();
Console.WriteLine(result);
}
//實體物件無條件更新
{
var result = await db.Update(new ProductModel() { ProductCode = "1001", ProductName = "測試產品1" }).ExecuteAsync();
Console.WriteLine(result);
}
//實體物件條件更新
{
var result = await db.Update(new ProductModel() { ProductCode = "1001", ProductName = "測試產品1" }).Where(w => w.ProductId == 1).ExecuteAsync();
Console.WriteLine(result);
}
//實體物件列表更新
{
var list = new List<ProductModel>();
for (int i = 0; i < 10; i++)
{
list.Add(new ProductModel() { ProductId = 16395 + i, ProductCode = $"{16395 + i}", ProductName = $"{16395 + i}" });
}
var result = await db.Update(list).ExecuteAsync();
Console.WriteLine(result);
}
//匿名物件無條件更新
{
var result = await db.Update(new { ProductCode = "1001", ProductName = "測試產品1" }).As("Product").ExecuteAsync();
Console.WriteLine(result);
}
//匿名物件條件更新
{
var result = await db.Update(new { ProductId = 1, ProductCode = "1001", ProductName = "測試產品1" }).Where(w => w.ProductId == 1).As("Product").ExecuteAsync();
Console.WriteLine(result);
}
//匿名物件列表更新 需要顯示指定主鍵名稱
{
var list = new List<object>();
for (int i = 0; i < 10; i++)
{
list.Add(new { ProductId = 16395 + i, ProductCode = $"{16395 + i}", ProductName = $"{16395 + i}" });
}
var result = await db.Update(list.ToList()).As("Product").Where("ProductId").ExecuteAsync();
Console.WriteLine(result);
}
#endregion
#region 查
//返回單個物件
{
var data = await db.Query<ProductModel>().Where(w => w.ProductId == 1).FirstAsync();
}
//返回列表
{
var data = await db.Query<ProductModel>().ToListAsync();
}
//返回字典
{
var data = await db.Query<ProductModel>().DictionaryAsync();
}
//返回字典列表
{
var data = await db.Query<ProductModel>().DictionaryListAsync();
}
//分頁查詢
{
var data = await db.Query<ProductModel>().ToPageListAsync(1, 10);
Console.WriteLine(JsonSerializer.Serialize(data.Data));//頁資料
Console.WriteLine($"總數:{data.Count}");
}
//聯表查詢
{
var data = await db.Query<ProductModel>().InnerJoin<ProductCategoryModel>((a, b) => a.CategoryId == b.CategoryId).ToListAsync();
}
//分組查詢
{
var data = await db.Query<ProductModel>().GroupBy(g => g.ProductName).Select(s => new { Count = 1.Count(), s.ProductName }).ToListAsync();
}
//排序查詢
{
var data = await db.Query<ProductModel>().OrderBy(o => o.ProductName).ToListAsync();
}
//動態條件表示式
{
var obj = new { ProductName = "測試" };
var ex = DynamicWhereExpression.Create<ProductModel>().AndIF(!string.IsNullOrWhiteSpace(obj.ProductName), a => a.ProductName == obj.ProductName);
var data = await db.Query<ProductModel>().Where(ex.Build()).ToListAsync();
}
// 合併查詢
{
var query1 = db.Query<ProductModel>().Where(w => w.ProductId < 100);
var query2 = db.Query<ProductModel>().Where(w => w.ProductId > 100);
var data = await db.UnionAll(query1, query2).ToListAsync();
}
#endregion
#region 批量複製 建議資料量達到500以上使用這個方法 僅支援 SqlServer MySql Oracle PostgreSql
{
var list = new List<ProductModel>();
for (int i = 1; i <= 10000; i++)
{
list.Add(new ProductModel() { ProductCode = i.ToString(), ProductName = $"測試{i}" });
}
// 因為 ProductModel 類還有其它屬性 所以需要使用 Select 擴充套件方法 顯示指定要匯入的屬性名稱和表名稱
var result = await db.BigData().BulkCopyAsync(list.Select(s => new { s.ProductCode, s.ProductName }), "Product");
Console.WriteLine(result);
}
#endregion