# Fast.Framework **Repository Path**: tengdays/Fast.Framework ## Basic Information - **Project Name**: Fast.Framework - **Description**: 基于NET 6.0 封装的轻量级ORM框架 - **Primary Language**: C# - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 11 - **Created**: 2022-04-08 - **Last Updated**: 2022-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## Fast Framework Author Mr-zhong Email 850856667@qq.com QQ群 693979005 Open Source https://gitee.com/China-Mr-zhong/Fast.Framework ##### 前言 为了实现快速开发,省去编写大量Sql时间,更好的面向对象编程由此诞生了 Fast Framework Fast Framework 是一个基于NET6.0 封装的轻量级 ORM 框架 支持数据库 SqlServer Oracle MySql PostgreSql Sqlite 由于底层使用System.Data.Common 抽象类封装 理论支持所有Ado.Net 实现的类库,差异部分可能需要额外处理。 优点: 体积小、流畅API、性能高、简单易用、表达式树智能解析 缺点:不具备有自动建库建表、数据迁移等复杂的功能 由于不同数据库差异较大 实现较为复杂 所以暂时不考虑实现 ##### 项目明细 1. Fast.Framework 2. Fast.Framework.CustomAttribute 3. Fast.Framework.Extensions 4. Fast.Framework.Interfaces 5. Fast.Framework.Logging 6. Fast.Framework.Models 7. Fast.Framework.Utils ##### 快速入门 手动创建 ```c# 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(options);//原生Ado var db = new DbContext(ado);//数据库上下文 ``` 依赖注入 ```c# var builder = WebApplication.CreateBuilder(args); // 正式项目请用配置文件注入,为了测试方便直接引用实现类库 builder.Services.AddScoped, Ado>(); builder.Services.AddScoped, DbContext>(); //加载Json配置文件 builder.Services.Configure(configuration.GetSection("DbFactory:MySqlDb")); ``` ##### 特性支持 原生支持微软封装好的特性,命名空间如下 using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations; - 示例 ```c# /// /// 产品模型 /// [Table("Product")] public class ProductModel { [Key] public int ProductId { get; set; } /// /// 分类ID /// public int CategoryId { get; set; } /// /// 产品编号 /// public string ProductCode { get; set; } /// /// 产品名称 /// public string ProductName { get; set; } /// /// 创建日期 /// public DateTime CreateDate { get; set; } /// /// 是否删除 /// public bool IsDelete { get; set; } } ``` ##### 插入 实体对象插入 ```c# var product = new ProductModel() { CategoryId = 1, ProductCode = "1001", ProductName = "测试产品1", CreateDate = DateTime.Now }; var result = await db.Insert(product).ExecuteAsync(); ``` 实体对象插入并返回自增ID 仅支持 SQLServer MySQL SQLite ```c# var product = new ProductModel() { CategoryId = 1, ProductCode = "1001", ProductName = "测试产品1", CreateDate = DateTime.Now }; var result = await db.Insert(product).ExecuteReturnIdentityAsync(); ``` 实体对象列表 批量插入 ```c# var list = new List() { new ProductModel() { CategoryId=1, ProductCode="1001", ProductName="测试产品1", CreateDate=DateTime.Now }, new ProductModel() { CategoryId=1, ProductCode="1002", ProductName="测试产品2", CreateDate=DateTime.Now, } }; var result = await db.Insert(list).ExecuteAsync(); ``` 匿名对象插入 需要使用As方法显示指定表名称 如需返回自增ID 同上 ```c# var product = new { CategoryId = 1, ProductCode = "1001", ProductName = "测试产品1", CreateDate = DateTime.Now }; var result = await db.Insert(product).As("Product").ExecuteAsync(); ``` 匿名对象列表批量插入 ```c# var list = new List() { new { CategoryId=1, ProductCode="1001", ProductName="测试产品1", CreateDate=DateTime.Now }, new { CategoryId=1, ProductCode="1002", ProductName="测试产品2", CreateDate=DateTime.Now, } }; var result = await db.Insert(list).As("Product").ExecuteAsync(); ``` 字典插入 注意需要显示使用 <类型> 否则将无法重载到正确的方法 ```c# var data = new Dictionary() { { "ProductCode","1001"}, { "ProdutName","测试产品1"}, { "CategoryId",1}, { "CreateDate",DateTime.Now} }; var result = await db.Insert(data).ExecuteAsync(); ``` ##### 删除 实体对象无条件删除 ```c# var result = await db.Delete().ExecuteAsync(); ``` 实体对象条件删除 ```c# var result = await db.Delete().Where(p => p.ProductId == 1).ExecuteAsync(); ``` 无实体删除 无条件删除场景很有用,特别用法 ```c# var result = await db.Delete().As("Product").ExecuteAsync(); ``` ##### 更新 实体对象更新 如果只是更新一条数据请务必带上Where条件 ```c# var product = new ProductModel() { ProductCode = "1001", ProductName = "测试产品1" }; var result = await db.Update(product).Where(p => p.ProductId == 1).ExecuteAsync(); ``` 实体对象表达式更新 如果只是更新一条数据请务必带上Where条件 ```c# var result = await db.Update(p => new ProductModel { ProductCode = "1001", ProductName = p.ProductCode + p.ProductName }).Where(p => p.ProductId == 1).ExecuteAsync(); ``` 实体对象列表 批量更新 默认会查找标注主键属性作为更新条件 如果没有主键 需要显示使用Where 方法指定条件列名称 ```c# var list = new List() { new ProductModel() { ProductId=1, CategoryId=1, ProductCode="1001", ProductName="测试产品1", CreateDate=DateTime.Now }, new ProductModel() { ProductId=2, CategoryId=1, ProductCode="1002", ProductName="测试产品2", CreateDate=DateTime.Now, } }; var result = await db.Update(list).ExecuteAsync(); ``` 匿名对象更新 需要使用As方法显示指定表名称 如果只是更新一条数据请务必带上Where条件 ```c# var product = new { ProductCode = "1001", ProductName = "测试产品1" }; var result = await db.Update(product).As("product").Where(p => p.ProductId == 1).ExecuteAsync(); ``` 字典更新 注意需要显示使用 <类型> 否则将无法重载到正确的方法 ```c# var data = new Dictionary() { { "ProductCode","1001"}, { "ProdutName","测试产品1"}, { "CategoryId",1}, { "CreateDate",DateTime.Now} }; var result = await db.Update(data).Where(p => p.ProductId == 1).ExecuteAsync(); ``` ##### 查询 单一对象 ```c# var data = await db.Query().FirstAsync(); ``` 列表 ```c# var data = await db.Query().ToListAsync(); ``` 分页 ```c# var pageData = await db.Query().ToPageListAsync(1, 10); ``` 单个字典 ```c# var data = await db.Query().DictionaryAsync(); ``` 字典列表 ```c# var data = await db.Query().DictionaryListAsync(); ``` 计数 ```c# var count = await db.Query().CountAsync(); ``` 任何 ```c# var count = await db.Query().AnyAsync(); ``` 条件 ```c# var data = await db.Query().Where(p => p.IsDelete == true).ToListAsync(); ``` In 有好几个重载方法 不全部列出 ```c# var data = await db.Query().In(p => p.ProductId, ids).ToListAsync(); ``` NotIn 有好几个重载方法 不全部列出 ```c# var data = await db.Query().NotIn(p => p.ProductId, ids).ToListAsync(); ``` 分组 ```c# var data = await db.Query().GroupBy(p => new { p.ProductCode, p.ProductName }).ToListAsync(); ``` HavaVing 需要和GroupBy 组合 ```c# var data = await db.Query().GroupBy(p => new { p.ProductCode, p.ProductName }).Having(p => SqlFunc.Count(1) > 1).ToListAsync(); ``` 排序 默认ASC 升序 ```c# var data = await db.Query().OrderBy(o => new { o.ProductId }, "DESC").ToListAsync(); ``` 并集 多个查询合并成一个 列名个数和数据类型需要一一对应 ```c# var query1 = db.Query().Select(s => new { s.ProductCode, s.ProductName }); var query2 = db.Query().Select(s => new { s.ProductCode, s.ProductName }); var data = db.Union(query1, query2).ToListAsync(); ``` 左连接 ```c# var data = db.Query() .LeftJoin((p, c) => p.CategoryId == c.CategoryId) .Select((p, c) => new { c.CategoryName, p.ProductCode, p.ProductName }).ToListAsync(); ``` 内连接 ```c# var data = db.Query() .InnerJoin((p, c) => p.CategoryId == c.CategoryId) .Select((p, c) => new { c.CategoryName, p.ProductCode, p.ProductName }).ToListAsync(); ``` 选择 返回指定字段 ```c# var data = db.Query().Select(p => new { p.ProductCode, p.ProductName }).ToListAsync(); ``` 模糊查询 StartsWith 左模糊 EndsWith 右模糊 Contains 全模糊 ```c# var data = db.Query().Where(p => p.ProductName.Contains("测试")).ToListAsync(); ``` 动态条件表达式 ```c# var ex = DynamicWhereExpression.Create(); // 两个子表达式参数名 p 必须一致 ex.AndIF(1 == 1, p => p.ProductCode == "1001"); ex.AndIF(1 == 1, p => p.ProductName == "测试"); var data = db.Query().Where(ex.Build()).ToListAsync(); ``` ##### 功能类 Fast.Framework.SqlFunc.cs Fast.Framework.Extensions.SqlFuncExtensionscs.cs 对比两种使用方式 两种方式是等价的 我更喜欢使用扩展方法 ```c# var data = db.Query().Select(s => new { Case1 = 1.Count(), Case2 = SqlFunc.Count(1) }).ToListAsync(); ``` 特殊方法Call 如果您需要在表达式new一个对象调用方法或者获取属性值 需要显示调用这个方法 因为表达式默认解析类型是SqlString ```c# var data = db.Query().Where(p => p.ProductCode == new { ProductCode = "123" }.Call().ProductCode).ToListAsync(); ``` ##### 输出Sql 使用Tostring() Insert Delete Update Query 对象都支持 ```c# var sql = db.Query().ToString(); Console.WriteLine(sql); ``` 日志委托 ```c# db.Ado.DbLog = (sql, parameters) => { Console.WriteLine($"ExecuteSql:{sql}"); if (parameters != null) { foreach (var item in parameters) { Console.WriteLine($"参数名:{item.ParameterName} 参数值:{item.Value}"); } } Console.WriteLine($"ExecuteTime:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); Console.WriteLine(); }; ``` ##### Ado 原生 如果DbContext 无法满足复杂查询需求 可以使用Ado原生满足各种复杂查询 ```c# // 这是一个简单的示例 仅供参考 var sql = "select * from product where productcode=@ProductCode;select 100;"; var paramters = new Dictionary() { { "ProductCode","1001"} }; var reader = db.Ado.ExecuteReaderAsync(sql, db.Ado.SqlParametersBuild(paramters)); var data = await reader.ListBuildAsync(); var count = await reader.FristBuildAsync(); ```