翼度科技»论坛 编程开发 .net 查看内容

一个可用于生产项目 基于 .NET 6 自研ORM

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
Fast Framework

作者 Mr-zhong
代码改变世界....
一、前言

Fast Framework 基于NET6.0 封装的轻量级 ORM 框架 支持多种数据库 SqlServer Oracle MySql PostgreSql Sqlite
优点: 体积小、可动态切换不同实现类库、原生支持微软特性、流畅API、使用简单、性能高、模型数据绑定采用 委托、强大的表达式解析、支持多种子查询可实现较为复杂查询、源代码可读性强。
缺点:目前仅支持Db Frist   Code Frist 后续迭代。
开源地址 https://github.com/China-Mr-zhong/Fast.Framework (唯一)
目前作者已使用该框架应用多个生产项目
个别亮点功能:数值类型绑定自动格式化小数点后面多余的0、表达式参数名称自动编排 无需强制统一参数名称
本作者不提供任何性能对比数据,请各位感兴趣的自行测试,对比前建议预热连接
二、项目明细

名称说明Fast.Framework框架主项目Fast.Framework.Logging基于微软接口实现的文件日志(非必要可不引用)Fast.Framework.Test控制台测试项目Fast.Framework.UnitTest单元测试项目Fast.Framework.Web.TestWeb测试项目三、核心对象


  • Ado 原生Ado对象
    1.                 IAdo ado = new AdoProvider(new DbOptions()
    2.                 {
    3.                     DbId = "1",
    4.                     DbType = DbType.MySQL,
    5.                     ProviderName = "MySqlConnector",
    6.                     FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
    7.                     ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout=30;"
    8.                 });
    复制代码
  • DbContext  支持多租户 支持切换不同Ado实现类库 设置 ProviderName和FactoryName 即可
    1.                 IDbContext db = new DbContext(new List<DbOptions>() {
    2.                 new DbOptions()
    3.                 {
    4.                     DbId = "1",
    5.                     DbType = DbType.MySQL,
    6.                     ProviderName = "MySqlConnector",
    7.                     FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
    8.                     ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout=30;"
    9.                 }});
    复制代码
  • DbOptions  Json文件配置格式
    1. "DbOptions": [
    2.     {
    3.       "DbId": 1,
    4.       "DbType": "SQLServer",
    5.       "ProviderName": "System.Data.SqlClient",
    6.       "FactoryName": "System.Data.SqlClient.SqlClientFactory,System.Data",
    7.       "ConnectionStrings": "server=localhost;database=Test;user=sa;pwd=123456789;min pool size=3;max pool size=100;connect timeout=120;"
    8.     }]
    复制代码
  • Asp.net Core 依赖注入
    1. // 注册服务
    2. var builder = WebApplication.CreateBuilder(args);
    3. // 添加数据库上下文
    4. builder.Services.AddFastDbContext();
    5. // 从Json配置文件加载数据库选项
    6. builder.Services.Configure<List<DbOptions>>(builder.Configuration.GetSection("DbOptions"));
    7. // 产品服务类 通过构造方法注入
    8. public class ProductService
    9. {
    10.     /// <summary>
    11.     /// 数据库
    12.     /// </summary>
    13.     private readonly IDbContext db;
    14.     /// <summary>
    15.     /// 构造方法
    16.     /// </summary>
    17.     /// <param name="db">数据库</param>
    18.     public ProductService(IDbContext db)
    19.     {
    20.         this.db = db;
    21.     }
    22. }
    复制代码
四、插入


  • 实体对象插入
    1.             var product = new Product()
    2.             {
    3.                 ProductCode = "1001",
    4.                 ProductName = "测试商品1"
    5.             };
    6.             var result = db.Insert(product).Exceute();
    7.             Console.WriteLine($"实体对象插入 受影响行数 {result}");
    复制代码
  • 实体对象插入并返回自增ID 仅支持 SQLServer MySQL SQLite
    1.             var product = new Product()
    2.             {
    3.                 ProductCode = "1001",
    4.                 ProductName = "测试产品1"
    5.             };
    6.             var result = db.Insert(product).ExceuteReturnIdentity();
    7.             Console.WriteLine($"实体对象插入 返回自增ID {result}");
    复制代码
  • 实体对象列表插入
    1.             var list = new List<Product>();
    2.             for (int i = 0; i < 2100; i++)
    3.             {
    4.                 list.Add(new Product()
    5.                 {
    6.                     ProductCode = $"编号{i + 1}",
    7.                     ProductName = $"名称{i + 1}"
    8.                 });
    9.             }
    10.             var result = db.Insert(list).Exceute();
    11.             Console.WriteLine($"实体对象列表插入 受影响行数 {result}");
    复制代码
  • 匿名对象插入
    1.             var obj = new
    2.             {
    3.                 ProductCode = "1001",
    4.                 ProductName = "测试商品1"
    5.             };
    6.             //注意:需要使用As方法显示指定表名称
    7.             var result = db.Insert(obj).As("Product").Exceute();
    8.             Console.WriteLine($"匿名对象插入 受影响行数 {result}");
    复制代码
  • 匿名对象列表插入
    1.             var list = new List<object>();
    2.             for (int i = 0; i < 2100; i++)
    3.             {
    4.                 list.Add(new
    5.                 {
    6.                     ProductCode = $"编号{i + 1}",
    7.                     ProductName = $"名称{i + 1}"
    8.                 });
    9.             }
    10.             //注意:需要使用As方法显示指定表名称
    11.             var result = db.Insert(list).As("Product").Exceute();
    12.             Console.WriteLine($"匿名对象列表插入 受影响行数 {result}");
    复制代码
  • 字典插入
    1.             var product = new Dictionary<string, object>()
    2.             {
    3.                 {"ProductCode","1001"},
    4.                 { "ProductName","测试商品1"}
    5.             };
    6.             var result = db.Insert(product).As("Product").Exceute();
    7.             Console.WriteLine($"字典插入 受影响行数 {result}");
    复制代码
  • 字典列表插入
    1.             var list = new List<Dictionary<string, object>>();
    2.             for (int i = 0; i < 2100; i++)
    3.             {
    4.                 list.Add(new Dictionary<string, object>()
    5.                 {
    6.                     {"ProductCode","1001"},
    7.                     { "ProductName","测试商品1"}
    8.                  });
    9.             }
    10.             var result = db.Insert(list).As("Product").Exceute();
    11.             Console.WriteLine($"字典列表插入 受影响行数 {result}");
    复制代码
五、删除


  • 实体对象删除
    1.             var product = new Product()
    2.             {
    3.                 ProductId = 1,
    4.                 ProductCode = "1001",
    5.                 ProductName = "测试商品1"
    6.             };
    7.             //注意:必须标记KeyAuttribute特性 否则将抛出异常
    8.             var result = db.Delete(product).Exceute();
    9.             Console.WriteLine($"实体删除 受影响行数 {result}");
    复制代码
  • 无条件删除
    1.             var result = db.Delete<Product>().Exceute();
    2.             Console.WriteLine($"无条件删除 受影响行数 {result}");
    复制代码
  • 表达式删除
    1.             var result = await db.Delete<Product>().Where(w => w.ProductId == 1).ExceuteAsync();
    2.             Console.WriteLine($"条件删除 受影响行数 {result}");
    复制代码
  • 特殊删除
    1.                               //特殊用法 如需单个条件或多个可搭配 WhereColumn或WhereColumns方法
    2.             var result = await db.Delete<object>().As("Product").ExceuteAsync();
    3.             Console.WriteLine($"无实体删除 受影响行数 {result}");
    复制代码
六、更新


  • 实体对象更新
    1.             var product = new Product()
    2.             {
    3.                 ProductId = 1,
    4.                 ProductCode = "1001",
    5.                 ProductName = "测试商品1"
    6.             };
    7.             //注意:标记KeyAuttribute特性属性或使用Where条件,为了安全起见全表更新将必须使用Where方法
    8.             var result = db.Update(product).Exceute();
    9.             Console.WriteLine($"对象更新 受影响行数 {result}");
    复制代码
  • 指定列更新
    1.             var result = db.Update<Product>(new Product() { ProductCode = "1001", ProductName = "1002" }).Columns("ProductCode", "ProductName").Exceute();
    2.                                                 // 字段很多的话可以直接new List<string>(){"列1","列2"}
    复制代码
  • 忽略列更新
    1.             var result = db.Update<Product>(new Product() { ProductCode = "1001", ProductName = "1002" }).IgnoreColumns("Custom1").Exceute();
    2.             // 同上使用方法一样
    复制代码
  • 实体对象列表更新
    1.             var list = new List<Product>();
    2.             for (int i = 0; i < 2022; i++)
    3.             {
    4.                 list.Add(new Product()
    5.                 {
    6.                     ProductCode = $"编号{i + 1}",
    7.                     ProductName = $"名称{i + 1}"
    8.                 });
    9.             }
    10.             //注意:标记KeyAuttribute特性属性或使用WhereColumns方法指定更新条件列
    11.             var result = db.Update(list).Exceute();
    12.             Console.WriteLine($"对象列表更新 受影响行数 {result}");
    复制代码
  • 匿名对象更新
    1.             var obj = new
    2.             {
    3.                 ProductId = 1,
    4.                 ProductCode = "1001",
    5.                 ProductName = "测试商品1"
    6.             };
    7.             //注意:需要显示指定表名称 以及更新条件 使用 Where或者WhereColumns方法均可
    8.             var result = db.Update(obj).As("product").WhereColumns("ProductId").Exceute();
    9.             Console.WriteLine($"匿名对象更新 受影响行数 {result}");
    复制代码
  • 匿名对象列表更新
    1.             var list = new List<object>();
    2.             for (int i = 0; i < 2022; i++)
    3.             {
    4.                 list.Add(new
    5.                 {
    6.                     ProductId = i + 1,
    7.                     ProductCode = $"编号{i + 1}",
    8.                     ProductName = $"名称{i + 1}"
    9.                 });
    10.             }
    11.             //由于是匿名对象需要显示指定表名称,使用WhereColumns方法指定更新条件列
    12.             var result = db.Update(list).As("Product").WhereColumns("ProductId").Exceute();
    13.             Console.WriteLine($"匿名对象列表更新 受影响行数 {result}");
    复制代码
  • 字典更新
    1.             var product = new Dictionary<string, object>()
    2.             {
    3.                 { "ProductId",1},
    4.                 {"ProductCode","1001"},
    5.                 { "ProductName","测试商品1"}
    6.             };
    7.             var result = db.Update(product).As("Product").WhereColumns("ProductId").Exceute();
    8.             Console.WriteLine($"字典更新 受影响行数 {result}");
    复制代码
  • 字典列表更新
    1.             var list = new List<Dictionary<string, object>>();
    2.             for (int i = 0; i < 2022; i++)
    3.             {
    4.                 list.Add(new Dictionary<string, object>()
    5.                 {
    6.                     { "ProductId",i+1},
    7.                     {"ProductCode",$"更新编号:{i+1}"},
    8.                     { "ProductName",$"更新商品:{i + 1}"}
    9.                 });
    10.             }
    11.             var result = db.Update(list).As("Product").WhereColumns("ProductId").Exceute();
    12.             Console.WriteLine($"字典列表更新 受影响行数 {result}");
    复制代码
  • 指定条件更新
    1.             var product = new Product()
    2.             {
    3.                 ProductId = 1,
    4.                 ProductCode = "1001",
    5.                 ProductName = "测试商品1"
    6.             };
    7.             var result = db.Update(product).Where(p => p.ProductId == 100).Exceute();
    8.             Console.WriteLine($"表达式更新 受影响行数 {result}");
    复制代码
  • 并发更新  乐观锁-版本控制
    1.                 //注意:仅支持非列表更新 版本列数据类型仅支持 object、string、Guid 时间类型存在精度丢失所以不做支持
    2.                                 var obj = db.Query<Product>().Where(w => w.ProductId == 1).Frist();
    3.                 obj.Custom1 = "测试版本控制修改";
    4.                                 //参数为 true 更新失败将抛出异常
    5.                 var result = db.Update(obj).ExceuteWithOptLock(true);
    复制代码
七、查询


  • 单一查询
    1.             var data = db.Query<Product>().First();
    复制代码
  • 列表查询
    1.             var data = db.Query<Product>().ToList();
    复制代码
  • 返回单个字典
    1.             var data = db.Query<Product>().ToDictionary();
    复制代码
  • 返回字典列表
    1.             var data = db.Query<Product>().ToDictionaryList();
    复制代码
  • 分页查询
    1.             //分页查询不返回总数
    2.             var data = db.Query<Product>().ToPageList(1,100);
    3.             //分页查询返回总数
    4.                         var total = 0;//定义总数变量
    5.                         var data = db.Query<Product>().ToPageList(1, 1, ref total);
    6.             Console.WriteLine($"总数:{total}");
    复制代码
  • 计数查询
    1.             var data = db.Query<Product>().Count();
    复制代码
  • 任何查询
    1.             var data = db.Query<Product>().Any();
    复制代码
  • 条件查询
    1.             var data = db.Query<Product>().Where(w => w.ProductId == 1).ToList;
    复制代码
  • Like 查询
    1.             var data = db.Query<Product>().Where(w => w.ProductName.StartsWith("左模糊") || w.ProductName.EndsWith("右模糊") || w.ProductName.Contains("全模糊")).ToList();
    复制代码
  • Not Like查询
    1. var data = db.Query<Product>().Where(w => !w.ProductName.StartsWith("左模糊") || !w.ProductName.EndsWith("右模糊") || !w.ProductName.Contains("全模糊")).ToList();
    2. //由于没有专门去扩展 Not Like 方法,可以用取反或使用比较变通实现 例如 w.ProductName.StartsWith("左模糊")==false
    3. //Mysql举例 最终解析后的结果为 `ProductName` Like '%左模糊' = 0 这种用法数据库是支持的 相当于 Not Like
    复制代码
  • Select查询 (选择字段)
    1.             var data = db.Query<Product>().Select(s => new
    2.             {
    3.                 s.ProductId,
    4.                 s.ProductName
    5.             }).ToList();
    复制代码
  • Select查询 (Case When)
    1.                 var data = db.Query<Product>().Select(s => new
    2.                 {
    3.                     CaseTest1 = SqlFunc.Case(s.Custom1).When("1").Then("xx1").When("2").Then("xx2").Else("xx3").End(),
    4.                     CaseTest2 = SqlFunc.CaseWhen<string>(s.Custom1 == "1").Then("xx1").When(s.Custom1 == "2").Then("xx2").Else("xx3").End()
    5.                 }).ToList();
    复制代码
  • 分组查询
    1.             var data = db.Query<Product>().GroupBy(s => new
    2.             {
    3.                 s.ProductId,
    4.                 s.ProductName
    5.             }).ToList();
    复制代码
  • 分组聚合查询
    1.             var sql = db.Query<Order>().InnerJoin<OrderDetail>((a, b) => a.OrderId == b.OrderId).GroupBy((a, b) => new
    2.             {
    3.                 a.OrderCode
    4.             }).Select((a, b) => new
    5.             {
    6.                 a.OrderCode,
    7.                 Sum_Qty = SqlFunc.Sum(b.Qty)//支持嵌套
    8.             }).ToList();
    复制代码
  • 排序查询
    1.             var data = db.Query<Product>().OrderBy(s => new
    2.             {
    3.                 s.CreateTime
    4.             }).ToList();
    5.             //这是多个字段排序使用方法 还有其它重载方法
    复制代码
  • Having查询
    1.             var data = db.Query<Product>().GroupBy(s => new
    2.             {
    3.                 s.ProductId,
    4.                 s.ProductName
    5.             }).Having(s => SqlFunc.Count(s.ProductId) > 1).ToList();
    6.             //必须先使用GroupBy方法 懂得都懂
    复制代码
  • 联表查询
    1.             var data = db.Query<Product>().LeftJoin<Class1>((a, b) => a.ProductId == b.ProductId).ToList();
    2.             // 右连接 RightJoin 内连接 InnerJoin 全连接 FullJoin
    复制代码
  • 联合查询
    1.             var query1 = db.Query<Product>();
    2.             var query2 = db.Query<Product>();
    3.             db.Union(query1, query2);//联合
    4.             db.UnionAll(query1, query2);//全联合
    5.             //执行查询调用Toxx方法
    复制代码
  • 查询并插入  仅支持同实例的数据库 跨库 个人还是建议 用事务分开写查询和插入
    1.                 //方式1
    2.                 var result1 = db.Query<Product>().Where(w => w.ProductId == 1489087).Select(s => new
    3.                 {
    4.                     s.ProductCode,
    5.                     s.ProductName
    6.                 }).Insert<Product>(p => new
    7.                 {
    8.                     p.ProductCode,
    9.                     p.ProductName
    10.                 });
    11.                 //方式2 需要注意的是 显示指定不带 列标识符 例如 `列名称1` 如有字段冲突 可自行加上标识符
    12.                 var result2 = db.Query<Product>().Where(w => w.ProductId == 1489087).Select(s => new
    13.                 {
    14.                     s.ProductCode,
    15.                     s.ProductName
    16.                 }).Insert("表名称 同实例不同库 可以使用 db.数据库名称.表名称 ", "列名称1", "列名称2", "`带标识的列名称3`");
    17.                 //方式3 需要注意同方式2 一样
    18.                 var result3 = db.Query<Product>().Where(w => w.ProductId == 1489087).Select(s => new
    19.                 {
    20.                     s.ProductCode,
    21.                     s.ProductName
    22.                 }).Insert("表名称 同实例不同库 可以使用 db.数据库名称.表名称 ", new List<string>() { "列名称1" });
    复制代码
  • In查询
    1.                 // 方式1
    2.                 var data1 = db.Query<Product>().Where(w => SqlFunc.In(w.ProductCode, "1001", "1002")).ToList();
    3.                 // 方式2
    4.                 var data2 = db.Query<Product>().Where(w => SqlFunc.In(w.ProductCode, new List<string>() { "123", "456" })).ToList();
    5.                 // 方式3 需要动态更新IN值 使用这种
    6.                 var list = new List<string>() { "123", "456" };
    7.                 var data3 = db.Query<Product>().Where(w => SqlFunc.In(w.ProductCode, list)).ToList();
    8.                 // 方法4 参数同上一样 单独分离IN和NotIN 是为了兼容匿名查询
    9.                 var data4 = db.Query<Product>().In("字段名称", "1001", "1002").ToList();
    复制代码
  • Select子查询
    1.                 var subQuery = db.Query<Product>().Where(w => w.ProductId == 1).Select(s => s.ProductName);
    2.                 var sql1 = db.Query<Product>().Select(s => new Product()
    3.                 {
    4.                     Custom1 = db.SubQuery<string>(subQuery)// SubQuery 的泛型是根据你左边赋值的属性类型来定义
    5.                 }).ToList();
    6.                 // 这种没有使用new 的 泛型可随意定义 实际作用就是避免 对象属性赋值类型冲突的问题
    7.                 var sql2 = db.Query<Product>().Select(s => db.SubQuery<string>(subQuery)).ToList();
    复制代码
  • From子查询
    1.                 var subQuery = db.Query<Product>();
    2.                 var data = db.Query(subQuery).OrderBy(o => o.ProductCode).ToList();
    复制代码
  • Join子查询
    1.                 var subQuery = db.Query<Product>();
    2.                 var data = db.Query<Product>().InnerJoin(subQuery, (a, b) => a.ProductId == b.ProductId).ToList();
    复制代码
  • Include查询
    1.                 // 联表条件 默认优先匹配主键 其次带有ID结尾的名称
    2.                 var data = db.Query<Category>().Include(i => i.Products).ToList();
    复制代码
八、Lambda表达式


  • 动态表达式  命名空间 Fast.Framework.Utils
    1.                 var ex = DynamicWhereExp.Create<Product>().AndIF(1 == 1, a => a.DeleteMark == true).Build();
    2.                 var data = db.Query<Product>().Where(ex).ToList();
    复制代码
  • Sql函数    自定义函数  需引入命名空间 Fast.Framework.Utils

    • SqlServer

      • 类型转换
        方法名称解析示例值说明自定义函数ToStringCONVERT( VARCHAR(255),123)转换 VARCHAR否ToDateTimeCONVERT( DATETIME,‘2022-09-16’)转换 DATETIME否ToDecimalCONVERT( DECIMAL(10,6),‘123’)转换 DECIMAL否ToDoubleCONVERT( NUMERIC(10,6),‘123’)转换 NUMERIC否ToSingleCONVERT( FLOAT,‘123’)转换 FLOAT否ToInt32CONVERT( INT,‘123’)转换 INT否ToInt64CONVERT( BIGINT,‘123’)转换 BIGINT否ToBooleanCONVERT( BIT,‘1’)转换 BIT否ToCharCONVERT( CHAR(2),'x')转换 CHAR否
      • 聚合函数
        方法名称解析示例值说明自定义函数MaxMAX( a.[xx] )最大值是MinMIN( a.[xx] )最小值是CountCOUNT( a.[xx] )计数是SumSUM( a.[xx] )合计是AvgAVG( a.[xx] )平均是
      • 数学函数
        方法名称解析示例值说明自定义函数AbsABS( a.[xx] )绝对值是RoundROUND( a.[xx] ,2 )四舍五入是
      • 字符串函数
        方法名称解析示例值说明自定义函数StartsWithLIKE ‘%’+'xx'左模糊否EndsWithLIKE 'xx'+‘%’右模糊否ContainsLIKE ‘%’+'xx'+‘%’全模糊否SubStringSUBSTRING( 'xxxxxx' ,1,3)截取否ReplaceREPLACE( 'xxx','x','y')替换否LenLEN( 'xxx' )长度是TrimStartLTRIM( ' xx ' )修剪起始空格否TrimEndRTRIM( ' xx ' )修剪末尾空格否ToUpperUPPER( 'xx' )大写否ToLowerLOWER( 'xx' )小写否OperationCreateTime >= @Now_1日期、数值、字符串范围比较是
      • 日期函数
        方法名称解析示例值说明自定义函数DateDiffDATEDIFF( DAY ,a.[xx],b.[xx])日期相差是AddYearsDATEADD( YEAR,a.[xx],1 )添加年份否AddMonthsDATEADD( MONTH,a.[xx],1 )添加月份否AddDaysDATEADD( DAY,a.[xx],1 )添加天数否AddHoursDATEADD( HOUR,a.[xx],1 )添加时否AddMinutesDATEADD( MINUTE,a.[xx],1 )添加分否AddSecondsDATEADD( SECOND,a.[xx],1 )添加秒否AddMillisecondsDATEADD( MILLISECOND,a.[xx],1 )添加毫秒否YearYEAR( a.[xx] )获取年份是MonthMONTH( a.[xx] )获取月份是DayDAY( a.[xx] )获取天数是
      • 查询函数
        方法名称解析示例值说明自定义函数InIN  ( a.[xx] ,'x1','x2','x3')In查询是NotInNOT IN  ( a.[xx] ,'x1','x2','x3')Not In查询是
      • 其它函数
        方法名称解析示例值说明自定义函数NewGuidNEWID()获取GUID否Equalsp.[ProductCode] = '123'比较否IsNullISNULL(a.[xx],0)是否为空是CaseCASEcase是WhenWHENwhen是ThenTHENthen是ElseELSEelse是EndENDend是

    • MySql

      • 类型转换
        方法名称解析示例值说明自定义函数ToStringCAST( a.`xx` AS CHAR(510) )转换 CHAR(510)否ToDateTimeCAST( a.`xx` AS DATETIME )转换 DATETIME否ToDecimalCAST( a.`xx` AS DECIMAL(10,6) )转换 DECIMAL(10,6)否ToDoubleCAST( a.`xx` AS DECIMAL(10,6) )转换 DECIMAL(10,6)否ToInt32CAST( a.`xx` AS DECIMAL(10) )转换 DECIMAL(10)否ToInt64CAST( a.`xx` AS DECIMAL(19) )转换 DECIMAL(19)否ToBooleanCAST( a.`xx`  AS UNSIGNED )转换 UNSIGNED否ToCharCAST( a.`xx` AS CHAR(2) )转换 CHAR(2)否
      • 聚合函数
        方法名称解析示例值说明自定义函数MaxMAX( a.`xx` )最大值是MinMIN( a.`xx` )最小值是CountCOUNT( a.`xx` )计数是SumSUM( a.`xx` )合计是AvgAVG( a.`xx` )平均是
      • 数学函数
        方法名称解析示例值说明自定义函数AbsABS( a.`xx` )绝对值是RoundROUND( a.`xx` ,2 )四舍五入是
      • 字符串函数
        方法名称解析示例值说明自定义函数StartsWithLIKE CONCAT( '%','xx' )左模糊否EndsWithLIKE CONCAT( xx','%' )右模糊否ContainsLIKE CONCAT( '%','xx','%' )全模糊否SubStringSUBSTRING(  'xxxxxx' ,1,3 )截取否ReplaceREPLACE( 'xxx','x','y' )替换否LenLEN( 'xxx' )长度是TrimTRIM( ' xx ' )修剪空格否TrimStartLTRIM( ' xx ' )修剪起始空格否TrimEndRTRIM( ' xx ' )修剪末尾空格否ToUpperUPPER( 'xx' )大写否ToLowerLOWER( 'xx' )小写否ConcatCONCAT(a.`xx1`,a.`xx2`)字符串拼接是
      • 日期函数
        方法名称解析示例值说明自定义函数DateDiffDATEDIFF( a.`xx`,b.`xx` )日期相差 返回相差天数是TimestampDiffTIMESTAMPDIFF( DAY,a.`xx`,b.`xx` )日期相差 指定时间单位是AddYearsDATE_ADD( a.`xx`,INTERVAL 1 YEAR )添加年份否AddMonthsDATE_ADD( a.`xx`,INTERVAL 1 MONTH )添加月份否AddDaysDATE_ADD( a.`xx`,INTERVAL 1 DAY )添加天数否AddHoursDATE_ADD( a.`xx`,INTERVAL 1 HOUR )添加时否AddMinutesDATE_ADD( a.`xx`,INTERVAL 1 MINUTE )添加分否AddSecondsDATE_ADD( a.`xx`,INTERVAL 1 SECOND )添加秒否AddMillisecondsDATE_ADD( a.`xx`,INTERVAL 1 MINUTE_SECOND )添加毫秒否YearYEAR( a.`xx` )获取年份是MonthMONTH( a.`xx` )获取月份是DayDAY( a.`xx` )获取天数是
      • 查询函数
        方法名称解析示例值说明自定义函数InIN  ( a.`xx` ,'x1','x2','x3' )In查询是NotInNOT IN  ( a.`xx` ,'x1','x2','x3' )Not In查询是
      • 其它函数
        方法名称解析示例值说明自定义函数NewGuidUUID()获取GUID否Equalsp.`ProductCode` = '123'比较否IfNullIFNULL( a.`xx`,0 )如果为空是CaseCASEcase是WhenWHENwhen是ThenTHENthen是ElseELSEelse是EndENDend是

    • Oracle

      • 类型转换
        方法名称解析示例值说明自定义函数ToStringCAST( a."xx" AS VARCHAR(255) )转换 VARCHAR否ToDateTimeTO_TIMESTAMP( a."xx" ,'yyyy-MM-dd hh:mi:ss.ff')转换 DATETIME否ToDecimalCAST( a."xx" AS DECIMAL(10,6) )转换 DECIMAL否ToDoubleCAST( a."xx" AS NUMBER )转换 NUMBER否ToSingleCAST( a."xx" AS FLOAT )转换 FLOAT否ToInt32CAST( a."xx" AS INT )转换 INT否ToInt64CAST( a."xx" AS NUMBER )转换 NUMBER否ToBooleanCAST( a."xx" AS CHAR(1) )转换 CHAR否ToCharCAST( a."xx" AS CHAR(2) )转换 CHAR否
      • 聚合函数
        方法名称解析示例值说明自定义函数MaxMAX( a."xx" )最大值是MinMIN( a."xx" )最小值是CountCOUNT( a."xx" )计数是SumSUM( a."xx" )合计是AvgAVG( a."xx" )平均是
      • 数学函数
        方法名称解析示例值说明自定义函数AbsABS( a."xx" )绝对值是RoundROUND( a."xx" ,2 )四舍五入是
      • 字符串函数
        方法名称解析示例值说明自定义函数StartsWithLIKE CONCAT( '%','xx' )左模糊否EndsWithLIKE CONCAT( 'xx','%' )右模糊否ContainsLIKE CONCAT( '%','xx','%' )全模糊否SubStringSUBSTRING( 'xxxxxx' ,1,3)截取否ReplaceREPLACE( 'xxx','x','y')替换否LengthLENGTH( 'xxx' )长度是TrimStartLTRIM( ' xx ' )修剪起始空格否TrimEndRTRIM( ' xx ' )修剪末尾空格否ToUpperUPPER( 'xx' )大写否ToLowerLOWER( 'xx' )小写否ConcatCONCAT(a."xx1",a."xx2")字符串拼接是
      • 日期函数
        方法名称解析示例值说明自定义函数YearEXTRACT( YEAR FROM a."xx" )获取年份是MonthEXTRACT( MONTH FROM a."xx" )获取月份是DayEXTRACT( DAY FROM a."xx" )获取天数是
      • 查询函数
        方法名称解析示例值说明自定义函数InIN  ( a."xx" ,'x1','x2','x3')In查询是NotInNOT IN  ( a."xx",'x1','x2','x3')Not In查询是
      • 其它函数
        方法名称解析示例值说明自定义函数Equalsp."ProductCode" = '123'比较否NvlNVL( a."xx",0 )空,默认是CaseCASEcase是WhenWHENwhen是ThenTHENthen是ElseELSEelse是EndENDend是

    • PostgreSql

      • 类型转换
        方法名称解析示例值说明自定义函数ToStringa."xx"::VARCHAR(255)转换 VARCHAR否ToDateTimea."xx"::TIMESTAMP转换 TIMESTAMP否ToDecimala."xx"::DECIMAL(10,6)转换 DECIMAL否ToDoublea."xx"::NUMERIC(10,6)转换 NUMERIC否ToSinglea."xx"::REAL转换 REAL否ToInt32a."xx"::INTEGER转换 INT否ToInt64a."xx"::BIGINT转换 BIGINT否ToBooleana."xx"::BOOLEAN转换 BOOLEAN否ToChara."xx"::CHAR(2)转换 CHAR否
      • 聚合函数
        方法名称解析示例值说明自定义函数MaxMAX( a."xx" )最大值是MinMIN( a."xx" )最小值是CountCOUNT( a."xx" )计数是SumSUM( a."xx" )合计是AvgAVG( a."xx" )平均是
      • 数学函数
        方法名称解析示例值说明自定义函数AbsABS( a."xx" )绝对值是RoundROUND( a."xx" ,2 )四舍五入是
      • 字符串函数
        方法名称解析示例值说明自定义函数StartsWithLIKE CONCAT( '%','xx' )左模糊否EndsWithLIKE CONCAT( 'xx','%' )右模糊否ContainsLIKE CONCAT( '%','xx','%' )全模糊否SubStringSUBSTRING(  'xxxxxx' ,1,3 )截取否ReplaceREPLACE( 'xxx','x','y' )替换否LengthLENGTH( 'xxx' )长度是TrimTRIM( ' xx ' )修剪空格否TrimStartLTRIM( ' xx ' )修剪起始空格否TrimEndRTRIM( ' xx ' )修剪末尾空格否ToUpperUPPER( 'xx' )大写否ToLowerLOWER( 'xx' )小写否ConcatCONCAT(a."xx1",a."xx2")字符串拼接是
      • 日期函数
        方法名称解析示例值说明自定义函数AddYearsa."xx" + INTERVAL '1 YEAR'添加年份否AddMonthsa."xx" + INTERVAL '1 MONTH'添加月份否AddDaysa."xx" + INTERVAL '1 DAY'添加天数否AddHoursa."xx" + INTERVAL '1 HOUR'添加时否AddMinutesa."xx" + INTERVAL '1 MINUTE'添加分否AddSecondsa."xx" + INTERVAL '1 SECOND'添加秒否AddMillisecondsa."xx" + INTERVAL '1 MINUTE_SECOND'添加毫秒否YearYEAR( a."xx" )获取年份是MonthMONTH( a."xx" )获取月份是DayDAY( a."xx" )获取天数是
      • 查询函数
        方法名称解析示例值说明自定义函数InIN  ( a."xx" ,'x1','x2','x3' )In查询是NotInNOT IN  ( a."xx" ,'x1','x2','x3' )Not In查询是
      • 其它函数
        方法名称解析示例值说明自定义函数Equalsp.”ProductCode“ = '123'比较否CaseCASEcase是WhenWHENwhen是ThenTHENthen是ElseELSEelse是EndENDend是

    • Sqlite

      • 类型转换
        方法名称解析示例值说明自定义函数ToStringCAST(a.[xx] AS TEXT )转换 TEXT否ToDateTimeDATETIME( a.[xx] )转换 DateTime否ToDecimalCAST(a.[xx] AS DECIMAL(10,6) )转换 DECIMAL否ToDoubleCAST(a.[xx] AS NUMERIC(10,6) )转换 NUMERIC否ToSingleCAST(a.[xx] AS FLOAT )转换 FLOAT否ToInt32CAST(a.[xx] AS INTEGER )转换 INTEGER否ToInt64CAST(a.[xx] AS BIGINT )转换 BIGINT否ToBooleanCAST(a.[xx] AS CHAR(1) )转换 CHAR否ToCharCAST(a.[xx] AS CHAR(2) )转换 CHAR否
      • 聚合函数
        方法名称解析示例值说明自定义函数MaxMAX( a.[xx] )最大值是MinMIN( a.[xx] )最小值是CountCOUNT( a.[xx] )计数是SumSUM( a.[xx] )合计是AvgAVG( a.[xx] )平均是
      • 数学函数
        方法名称解析示例值说明自定义函数AbsABS( a.[xx] )绝对值是RoundROUND( a.[xx] ,2 )四舍五入是
      • 字符串函数
        方法名称解析示例值说明自定义函数StartsWithLIKE '%'||'xx'左模糊否EndsWithLIKE 'xx'||'%'右模糊否ContainsLIKE '%'||'xx'||'%'全模糊否SubStringSUBSTRING(  'xxxxxx' ,1,3 )截取否ReplaceREPLACE( 'xxx','x','y' )替换否LengthLENGTH( 'xxx' )长度是TrimTRIM( ' xx ' )修剪空格否TrimStartLTRIM( ' xx ' )修剪起始空格否TrimEndRTRIM( ' xx ' )修剪末尾空格否ToUpperUPPER( 'xx' )大写否ToLowerLOWER( 'xx' )小写否
      • 日期函数
        方法名称解析示例值说明自定义函数AddYearsDATETIME( a.[xx],'1 YEAR' )添加年份否AddMonthsDATETIME( a.[xx],'1 MONTH' )添加月份否AddDaysDATETIME( a.[xx],'1 DAY' )添加天数否AddHoursDATETIME( a.[xx],'1 HOUR' )添加时否AddMinutesDATETIME( a.[xx],'1 MINUTE' )添加分否AddSecondsDATETIME( a.[xx],'1 SECOND' )添加秒否AddMillisecondsDATETIME( a.[xx],'1 YEAR' )添加毫秒否YearSTRFTIME( '%Y', a.[xx] )获取年份是MonthSTRFTIME( '%m', a.[xx] )获取月份是DaySTRFTIME( '%j', a.[xx] )获取天数是
      • 查询函数
        方法名称解析示例值说明自定义函数InIN  ( a."xx" ,'x1','x2','x3' )In查询是NotInNOT IN  ( a."xx" ,'x1','x2','x3' )Not In查询是
      • 其它函数
        方法名称解析示例值说明自定义函数Equalsp.”ProductCode“ = '123'比较否CaseCASEcase是WhenWHENwhen是ThenTHENthen是ElseELSEelse是EndENDend是


  • 添加自定义函数解析
    1.                 //注意:只能扩展未实现的方法名称 不能覆盖原有的实现
    2.                 Models.DbType.MySQL.AddSqlFunc("方法名称", (visit, method, sqlStack) =>
    3.                 {
    4.                     //解析逻辑
    5.                 });
    复制代码
九、数据库日志
  1.                                         db.Aop.DbLog = (sql, dp) =>
  2.                 {
  3.                     Console.WriteLine($"执行Sql:{sql}");
  4.                     if (dp != null)
  5.                     {
  6.                         foreach (var item in dp)
  7.                         {
  8.                             Console.WriteLine($"参数名称:{item.ParameterName} 参数值:{item.ParameterValue}");
  9.                         }
  10.                     }
  11.                 };
复制代码
十、事务


  • 普通事务
    1.               try
    2.               {
    3.                   db.Ado.BeginTran();//开启事务
    4.                   // 执行 CRUD
    5.                   db.Ado.CommitTran();//提交事务
    6.               }
    7.               catch (Exception ex)
    8.               {
    9.                   Console.WriteLine(ex.Message);
    10.                   db.Ado.RollbackTran();//回滚事务
    11.               }
    复制代码
  • 更大范围的事务
    1.                 try
    2.                 {
    3.                     db.BeginTran();//开启事务
    4.                           // 执行 CRUD
    5.                     db.CommitTran();//提交事务
    6.                 }
    7.                 catch (Exception ex)
    8.                 {
    9.                     db.RollbackTran();//回滚事务
    10.                     Console.WriteLine(ex.Message);
    11.                 }
    复制代码
十一、多租户


  • 改变数据库
    1.                 //数据库配置可从Json配置文件加载
    2.                                 IDbContext db = new DbContext(new List<DbOptions>() {
    3.                 new DbOptions()
    4.                 {
    5.                     DbId = "1",
    6.                     DbType = Models.DbType.SQLServer,
    7.                     ProviderName = "System.Data.SqlClient",
    8.                     FactoryName = "System.Data.SqlClient.SqlClientFactory,System.Data",
    9.                     ConnectionStrings = "server=localhost;database=Test;user=sa;pwd=123456789;min pool size=0;max pool size=100;connect timeout=120;"
    10.                 },
    11.                 new DbOptions()
    12.                 {
    13.                     DbId = "2",
    14.                     DbType = Models.DbType.MySQL,
    15.                     ProviderName = "MySqlConnector",
    16.                     FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",
    17.                     ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;"
    18.                 }});
    19.                 db.ChangeDb("2");//切换到MySQL
    复制代码
十二、原生特性支持
  1.     /// <summary>
  2.     /// 产品
  3.     /// </summary>
  4.     [Table("ProductMain")]
  5.     public class Product
  6.     {
  7.         /// <summary>
  8.         /// 产品ID
  9.         /// </summary>
  10.         [Key]
  11.         public int ProductId { get; set; }
  12.         /// <summary>
  13.         /// 产品编号
  14.         /// </summary>
  15.         [Column("ProductCode")]//不标记默认取当前属性名称
  16.         public string ProductCode { get; set; }
  17.         /// <summary>
  18.         /// 自定义1
  19.         /// </summary>
  20.         [NotMapped]
  21.         public string Custom1 { get; set; }
  22.     }
复制代码
十三、原生Ado
  1.                 // 原始起步
  2.                 // var conn = db.Ado.DbProviderFactory.CreateConnection();
  3.                 // var cmd = conn.CreateCommand();
  4.                 // 封装的方法分别以Execute和Create开头以及预处理 PrepareCommand 方法
  5.                 // 该方法可以自动帮你处理执行的预操作,主要作用是代码复用。
  6.                 // 当有非常复杂的查询 ORM不能满足需求的时候可以使用原生Ado满足业务需求
  7.                 // 构建数据集核心扩展方法 分别有 FristBuild ListBuild DictionaryBuild DictionaryListBuild
  8.                 var data = db.Ado.ExecuteReader(CommandType.Text, "select * from product", null).ListBuild<Product>();
复制代码
十四、工作单元


  • 注册数据库上下文和工作单元服务
    1. var builder = WebApplication.CreateBuilder(args);
    2. var configuration = builder.Configuration;
    3. // 添加数据库上下文服务
    4. builder.Services.AddFastDbContext();
    5. // 添加工作单元服务
    6. builder.Services.AddFastUnitOfWork();
    7. // 加载数据库配置
    8. builder.Services.Configure<List<DbOptions>>(configuration.GetSection("DbConfig"));
    复制代码
  • 实际应用
    1.         /// <summary>
    2.         /// 工作单元
    3.         /// </summary>
    4.         private readonly IUnitOfWork unitOfWork;
    5.         /// <summary>
    6.         /// 构造方法
    7.         /// </summary>
    8.         /// <param name="unitOfWork">工作单元</param>
    9.         public UnitOfWorkTestService(IUnitOfWork unitOfWork)
    10.         {
    11.             this.unitOfWork = unitOfWork;
    12.         }
    13.         /// <summary>
    14.         /// 测试
    15.         /// </summary>
    16.         /// <returns></returns>
    17.         public string Test()
    18.         {
    19.             //unitOfWork 对象无需显示使用using
    20.             var result1 = unitOfWork.Db.Insert(new Category()
    21.             {
    22.                 CategoryName = "类别3"
    23.             }).Exceute();
    24.             var result2 = unitOfWork.Db.Insert(new Product()
    25.             {
    26.                 ProductCode = "测试工作单元",
    27.             }).Exceute();
    28.             unitOfWork.Commit();
    29.             return "工作单元执行完成...";
    30.         }
    复制代码
十五、大数据导入

<ul>批复制 仅支持SqlServer Oracle MySql PostgreSql
[code]                var list = new List();                for (int j = 1; j

举报 回复 使用道具