Fast Framework

作者 Mr-zhong

代码改变世界....

一、前言

Fast Framework 基于NET6.0 封装的轻量级 ORM 框架 支持多种数据库 SqlServer Oracle MySql PostgreSql Sqlite

优点: 体积小、原生支持微软特性、流畅API、使用简单、性能高、模型数据绑定采用 Expression、强大的表达式解析、支持多种子查询可实现较为复杂查询、源代码可读性强、支持AOT 编译。

缺点:目前仅支持Db Frist

ps:此版本不再支持动态切换数据库驱动,依旧支持热重载DbOptions

AOT编译经验分享

1.不要在方法里根据名称去动态获取方法信息

2.不要使用Emit

3.不要使用dynamic 关键字 使用object 代替

4.配置 rd.xml 文件

5.Json序列化不要使用 System.Text.Json 可以使用 Newtonsoft.Json 替代

6.不要在同一个解决方案去依赖使用反射项目的类库,需编译后单独引用,否则编译有问题

二、项目明细
名称 说明
Fast.Framework ORM
Fast.Framework.Logging 文件日志 (扩展项目可不使用)
Fast.Framework.DependencyInjection 依赖注入 (扩展项目可不使用) 不支持AOT
Fast.Framework.Test 控制台测试项目
Fast.Framework.UnitTest 单元测试项目
Fast.Framework.Web.Test Web测试项目
三、核心对象
  • Ado

    1. IAdo ado = new AdoProvider(new DbOptions()
    2. {
    3. DbId = "1",
    4. DbType = DbType.MySQL,
    5. ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout=30;"
    6. });
  • DbContext 支持多租户 支持切换不同Ado实现类库 设置 ProviderName和FactoryName 即可

    1. IDbContext db = new DbContext(new List<DbOptions>() {
    2. new DbOptions()
    3. {
    4. DbId = "1",
    5. DbType = DbType.MySQL,
    6. ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=3;max pool size=100;connect timeout=30;"
    7. }});
  • DbOptions Json文件配置格式

    1. "DbOptions": [
    2. {
    3. "DbId": 1,
    4. "DbType": "SQLServer",
    5. "ConnectionStrings": "server=localhost;database=Test;user=sa;pwd=123456789;min pool size=3;max pool size=100;connect timeout=120;"
    6. }]
  • 主从分离(读写分离)配置

    1. "DbOptions": [
    2. {
    3. "DbId": 2,
    4. "DbType": "MySQL",
    5. "IsDefault": true,
    6. "ConnectionStrings": "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",
    7. "UseMasterSlaveSeparation": true,//使用主从分离 注意所有事务将强制走主库
    8. "SlaveItems": [
    9. {
    10. "Weight": 1,//注意多个从库 必须配置权重且总权重>从库数
    11. "ConnectionStrings": "server=localhost;database=Test1;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",
    12. "Description": "从库连接配置"
    13. },
    14. {
    15. "Weight": 2,
    16. "ConnectionStrings": "server=localhost;database=Test2;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",
    17. "Description": "从库连接配置"
    18. }
    19. ],
    20. "Description": "主库连接配置"
    21. }
    22. ]
  • 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();
  • 实体对象插入并返回自增ID 仅支持 SQLServer MySQL SQLite

    1. var product = new Product()
    2. {
    3. ProductCode = "1001",
    4. ProductName = "测试产品1"
    5. };
    6. var result = db.Insert(product).ExceuteReturnIdentity();
  • 实体对象列表插入

    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();
  • 匿名对象插入

    1. var obj = new
    2. {
    3. ProductCode = "1001",
    4. ProductName = "测试商品1"
    5. };
    6. //注意:需要使用As方法显示指定表名称
    7. var result = db.Insert(obj).As("Product").Exceute();
  • 匿名对象列表插入

    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();
  • 字典插入

    1. var product = new Dictionary<string, object>()
    2. {
    3. {"ProductCode","1001"},
    4. { "ProductName","测试商品1"}
    5. };
    6. var result = db.Insert(product).As("Product").Exceute();
  • 字典列表插入

    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();
五、删除
  • 实体对象删除

    1. var product = new Product()
    2. {
    3. ProductId = 1,
    4. ProductCode = "1001",
    5. ProductName = "测试商品1"
    6. };
    7. var result = db.Delete(product).Exceute();
  • 实体对象列表删除

    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.Delete(list).Exceute();
  • 无条件删除

    1. var result = db.Delete<Product>().Exceute();
  • 条件删除

    1. var result = await db.Delete<Product>().Where(w => w.ProductId == 1).ExceuteAsync();
  • 逻辑删除

    1. /*
    2. 可用特性标记逻辑删除列 仅支持 int bool datetime 类型,其它类型不合适
    3. /// <summary>
    4. /// 删除标记
    5. /// </summary>
    6. [Logic]
    7. public bool DeleteMark { get; set; }
    8. */
    9. //额外设置其它属性值,使用SetColumns方法前需先使用IsLogic方法
    10. //类型逻辑删除
    11. var result1 = db.Delete<Product>().IsLogic().SetColumns(c => new Product()
    12. {
    13. ModifyTime = DateTime.Now
    14. }).Where(w => w.ProductId == 1).Exceute();
    15. //对象逻辑删除
    16. var result2 = db.Delete(new Product() { ProductId = 1 }).IsLogic().SetColumns(c => new Product()
    17. {
    18. ModifyTime = DateTime.Now
    19. }).Exceute();
    20. //特殊逻辑删除(不想建实体类可以用该方式)
    21. var result3 = db.Delete<object>().As("Product").IsLogic().SetColumns(c => new
    22. {
    23. ModifyTime = DateTime.Now
    24. }).Exceute();
  • 特殊删除

    1. //特殊用法 如需单个条件或多个可搭配 Where或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();
  • 指定列更新

    1. var result = db.Update<Product>(new Product() { ProductCode = "1001", ProductName = "1002" }).UpdateColumns(c=> new { c.ProductCode , c.ProductName }).Exceute();
    2. // 推荐使用表达式 c=>new {} 好处更改属性名称可以同步修改
  • 忽略列更新

    1. var result = db.Update<Product>(new Product() { ProductCode = "1001", ProductName = "1002" }).IgnoreColumns(c=> new { c.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();
  • 匿名对象更新

    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();
  • 匿名对象列表更新

    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();
  • 字典更新

    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();
  • 字典列表更新

    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();
  • 设置列更新

    1. // 设置列更新
    2. db.Update<Product>().SetColumns(c => new Product()
    3. {
    4. ProductCode = "1001",
    5. ProductName = "测试产品1"
    6. }).Where(w => w.ProductId == 1).Exceute();
  • 指定条件更新

    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();
  • 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. /// <summary>
    2. /// 类别
    3. /// </summary>
    4. public class Category
    5. {
    6. /// <summary>
    7. /// 类别ID
    8. /// </summary>
    9. [Key]
    10. public int CategoryId { get; set; }
    11. /// <summary>
    12. /// 类别名称
    13. /// </summary>
    14. public string CategoryName { get; set; }
    15. /// <summary>
    16. /// 产品 Navigate MainName和ChildName 可不显示指定,会自动查找主键匹配或ID为结尾的属性
    17. /// </summary>
    18. [Navigate(MainName = nameof(CategoryId), ChildName = nameof(Product.CategoryId))]
    19. public IEnumerable<Product> Products { get; set; }
    20. }
    21. var data = db.Query<Category>()
    22. .Include(i => i.Products)
    23. .ToList();
  • 查询并插入 仅支持同实例的数据库 跨库 个人还是建议 用事务分开写查询和插入

    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
    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");
    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. var data1 = db.Query<Product>().Where(w => new List<string>(){"1001", "1002"}.Contains(w.ProductCode)).ToList();
  • Select嵌套查询和子查询

    1. var data1 = db.Query<Product>().Select(s => new
    2. {
    3. XX = db.Query<Product>().Select(s => 1).First()//需调用返回结果的方法 否则无法解析
    4. }).First();
    5. //进价用法,下面示例方法的重载均支持
    6. var count = 0;
    7. var refAsync = new RefAsync<int>();
    8. var query = db.Query<Product>().Select(s => new
    9. {
    10. WithAttr_First = db.QueryWithAttr<Product>().First(),
    11. WithAttr_FirstAsync = db.QueryWithAttr<Product>().FirstAsync(),
    12. WithAttr_ToList = db.QueryWithAttr<Product>().ToList(),
    13. WithAttr_ToListAsync = db.QueryWithAttr<Product>().ToListAsync(),
    14. First_1 = db.Query<Category>().Select(s => 1).First(),//解析成Sql
    15. First = db.Query<Category>().First(),
    16. FirstAsync = db.Query<Category>().FirstAsync(),
    17. ToArray = db.Query<Category>().ToArray(),
    18. ToArrayAsync = db.Query<Category>().ToArrayAsync(),
    19. ToList = db.Query<Category>().ToList(),
    20. ToListAsync = db.Query<Category>().ToListAsync(),
    21. ToPageList = db.Query<Category>().ToPageList(1, 10),
    22. ToPageListAsync = db.Query<Category>().ToPageListAsync(1, 10),
    23. ToPageList_Count = db.Query<Category>().ToPageList(1, 10, ref count),
    24. ToPageListAsync_Count = db.Query<Category>().ToPageListAsync(1, 10, refAsync),
    25. ToDictionary = db.Query<Category>().ToDictionary(),
    26. ToDictionaryAsync = db.Query<Category>().ToDictionaryAsync(),
    27. ToDictionaryList = db.Query<Category>().ToDictionaryList(),
    28. ToDictionaryListAsync = db.Query<Category>().ToDictionaryListAsync(),
    29. ToDictionaryPageList = db.Query<Category>().ToDictionaryPageList(1, 10),
    30. ToDictionaryPageListAsync = db.Query<Category>().ToDictionaryPageListAsync(1, 10),
    31. ToDictionaryPageList_Count = db.Query<Category>().ToDictionaryPageList(1, 10, ref count),
    32. ToDictionaryPageListAsync_Count = db.Query<Category>().ToDictionaryPageListAsync(1, 10, refAsync),
    33. ToDataTable = db.Query<Category>().ToDataTable(),
    34. ToDataTableAsync = db.Query<Category>().ToDataTableAsync(),
    35. Max = db.Query<Category>().Max(a => a.CategoryId),//解析成Sql
    36. MaxAsync = db.Query<Category>().MaxAsync(a => a.CategoryId),
    37. Min = db.Query<Category>().Min(a => a.CategoryId),//解析成Sql
    38. MinAsync = db.Query<Category>().MinAsync(a => a.CategoryId),
    39. Count = db.Query<Category>().Count(),//解析成Sql
    40. CountAsync = db.Query<Category>().CountAsync(),
    41. Sum = db.Query<Category>().Sum(s => s.CategoryId),//解析成Sql
    42. SumAsync = db.Query<Category>().SumAsync(s => s.CategoryId),
    43. Avg = db.Query<Category>().Avg(s => s.CategoryId),//解析成Sql
    44. AvgAsync = db.Query<Category>().AvgAsync(s => s.CategoryId)
    45. });
    46. var data2= query.First();
  • From子查询

    1. var subQuery2 = db.Query<Product>().Select(s=>new
    2. {
    3. s.ProductId,
    4. s.CategoryId,
    5. s.ProductCode,
    6. s.ProductName,
    7. s.DeleteMark
    8. });
    9. var data = db.Query(subQuery2).ToList();
  • Join子查询

    1. var subQuery1 = db.Query<Product>().Select(s => new
    2. {
    3. s.ProductId,
    4. s.CategoryId,
    5. s.ProductCode,
    6. s.ProductName,
    7. s.DeleteMark
    8. });
    9. var data = db.Query<Category>().InnerJoin(subQuery1, (a, b) => a.CategoryId == b.CategoryId).ToList();
  • Include查询

    1. // 联表条件 默认优先匹配主键 其次带有ID结尾的名称
    2. var data = db.Query<Category>().Include(i => i.Products).ToList();
  • Exists查询

    1. var data = db.Query<Product>()
    2. .Where(w => db.Query<Product>().WhereIF(!string.IsNullOrWhiteSpace("测试"), a => a.ProductId == 1).Select(s => 1).Any())
    3. .Select(s => new
    4. {
    5. s.ProductId,
    6. s.ProductCode
    7. }).ToList();
  • 查询绑定字段(注意 字段必须是公开的,否则绑定外部无法访问,没有意义)

    1. //当某些字段需要参与计算并且不返回前端时推荐用字段绑定,无需从A实体转换到B实体,强烈推荐此方式
    2. var data = db.Query<Product>().Select(s => new Product()
    3. {
    4. _xx = s.ProductName
    5. }).First();
八、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 使用SqlFunc类

    • SqlServer

      • 类型转换

        方法名称 解析示例值 说明 自定义函数
        ToString CONVERT( VARCHAR(255),123) 转换 VARCHAR
        ToDateTime CONVERT( DATETIME,‘2022-09-16’) 转换 DATETIME
        ToDecimal CONVERT( DECIMAL(10,6),‘123’) 转换 DECIMAL
        ToDouble CONVERT( NUMERIC(10,6),‘123’) 转换 NUMERIC
        ToSingle CONVERT( FLOAT,‘123’) 转换 FLOAT
        ToInt32 CONVERT( INT,‘123’) 转换 INT
        ToInt64 CONVERT( BIGINT,‘123’) 转换 BIGINT
        ToBoolean CONVERT( BIT,‘1’) 转换 BIT
        ToChar CONVERT( CHAR(2),'x') 转换 CHAR
      • 聚合函数

        方法名称 解析示例值 说明 自定义函数
        Max MAX( a.[xx] ) 最大值
        Min MIN( a.[xx] ) 最小值
        Count COUNT( a.[xx] ) 计数
        Sum SUM( a.[xx] ) 合计
        Avg AVG( a.[xx] ) 平均
      • 数学函数

        方法名称 解析示例值 说明 自定义函数
        Abs ABS( a.[xx] ) 绝对值
        Round ROUND( a.[xx] ,2 ) 四舍五入
      • 字符串函数

        方法名称 解析示例值 说明 自定义函数
        StartsWith LIKE 'xx'+‘%’ 左模糊
        EndsWith LIKE ‘%’+'xx' 右模糊
        Contains LIKE ‘%’+'xx'+‘%’ 全模糊
        SubString SUBSTRING( 'xxxxxx' ,1,3) 截取
        Replace REPLACE( 'xxx','x','y') 替换
        Len LEN( 'xxx' ) 长度
        TrimStart LTRIM( ' xx ' ) 修剪起始空格
        TrimEnd RTRIM( ' xx ' ) 修剪末尾空格
        ToUpper UPPER( 'xx' ) 大写
        ToLower LOWER( 'xx' ) 小写
        Concat CONCAT(a.[xx1],a.[xx2]) 字符串拼接
        Operation [CreateTime] >= @Now_1 日期、数值、字符串范围比较
      • 日期函数

        方法名称 解析示例值 说明 自定义函数
        DateDiff DATEDIFF( DAY ,a.[xx],b.[xx]) 日期相差
        AddYears DATEADD( YEAR,a.[xx],1 ) 添加年份
        AddMonths DATEADD( MONTH,a.[xx],1 ) 添加月份
        AddDays DATEADD( DAY,a.[xx],1 ) 添加天数
        AddHours DATEADD( HOUR,a.[xx],1 ) 添加时
        AddMinutes DATEADD( MINUTE,a.[xx],1 ) 添加分
        AddSeconds DATEADD( SECOND,a.[xx],1 ) 添加秒
        AddMilliseconds DATEADD( MILLISECOND,a.[xx],1 ) 添加毫秒
        Year YEAR( a.[xx] ) 获取年份
        Month MONTH( a.[xx] ) 获取月份
        Day DAY( a.[xx] ) 获取天数
      • 其它函数

        方法名称 解析示例值 说明 自定义函数
        NewGuid NEWID() 获取GUID
        Equals p.[ProductCode] = '123' 比较
        IsNull ISNULL(a.[xx],0) 是否为空
        Case CASE case
        When WHEN when
        Then THEN then
        Else ELSE else
        End END end
    • MySql

      • 类型转换

        方法名称 解析示例值 说明 自定义函数
        ToString CAST( a.`xx` AS CHAR(510) ) 转换 CHAR(510)
        ToDateTime CAST( a.`xx` AS DATETIME ) 转换 DATETIME
        ToDecimal CAST( a.`xx` AS DECIMAL(10,6) ) 转换 DECIMAL(10,6)
        ToDouble CAST( a.`xx` AS DECIMAL(10,6) ) 转换 DECIMAL(10,6)
        ToInt32 CAST( a.`xx` AS DECIMAL(10) ) 转换 DECIMAL(10)
        ToInt64 CAST( a.`xx` AS DECIMAL(19) ) 转换 DECIMAL(19)
        ToBoolean CAST( a.`xx` AS UNSIGNED ) 转换 UNSIGNED
        ToChar CAST( a.`xx` AS CHAR(2) ) 转换 CHAR(2)
      • 聚合函数

        方法名称 解析示例值 说明 自定义函数
        Max MAX( a.`xx` ) 最大值
        Min MIN( a.`xx` ) 最小值
        Count COUNT( a.`xx` ) 计数
        Sum SUM( a.`xx` ) 合计
        Avg AVG( a.`xx` ) 平均
      • 数学函数

        方法名称 解析示例值 说明 自定义函数
        Abs ABS( a.`xx` ) 绝对值
        Round ROUND( a.`xx` ,2 ) 四舍五入
      • 字符串函数

        方法名称 解析示例值 说明 自定义函数
        StartsWith LIKE CONCAT( 'xx','%' ) 左模糊
        EndsWith LIKE CONCAT( '%','xx' ) 右模糊
        Contains LIKE CONCAT( '%','xx','%' ) 全模糊
        SubString SUBSTRING( 'xxxxxx' ,1,3 ) 截取
        Replace REPLACE( 'xxx','x','y' ) 替换
        Len LEN( 'xxx' ) 长度
        Trim TRIM( ' xx ' ) 修剪空格
        TrimStart LTRIM( ' xx ' ) 修剪起始空格
        TrimEnd RTRIM( ' xx ' ) 修剪末尾空格
        ToUpper UPPER( 'xx' ) 大写
        ToLower LOWER( 'xx' ) 小写
        Concat CONCAT(a.`xx1`,a.`xx2`) 字符串拼接
        Operation `CreateTime` >= @Now_1 日期、数值、字符串范围比较
      • 日期函数

        方法名称 解析示例值 说明 自定义函数
        DateDiff DATEDIFF( a.`xx`,b.`xx` ) 日期相差 返回相差天数
        TimestampDiff TIMESTAMPDIFF( DAY,a.`xx`,b.`xx` ) 日期相差 指定时间单位
        AddYears DATE_ADD( a.`xx`,INTERVAL 1 YEAR ) 添加年份
        AddMonths DATE_ADD( a.`xx`,INTERVAL 1 MONTH ) 添加月份
        AddDays DATE_ADD( a.`xx`,INTERVAL 1 DAY ) 添加天数
        AddHours DATE_ADD( a.`xx`,INTERVAL 1 HOUR ) 添加时
        AddMinutes DATE_ADD( a.`xx`,INTERVAL 1 MINUTE ) 添加分
        AddSeconds DATE_ADD( a.`xx`,INTERVAL 1 SECOND ) 添加秒
        AddMilliseconds DATE_ADD( a.`xx`,INTERVAL 1 MINUTE_SECOND ) 添加毫秒
        Year YEAR( a.`xx` ) 获取年份
        Month MONTH( a.`xx` ) 获取月份
        Day DAY( a.`xx` ) 获取天数
      • 其它函数

        方法名称 解析示例值 说明 自定义函数
        NewGuid UUID() 获取GUID
        Equals p.`ProductCode` = '123' 比较
        IfNull IFNULL( a.`xx`,0 ) 如果为空
        Case CASE case
        When WHEN when
        Then THEN then
        Else ELSE else
        End END end
    • Oracle

      • 类型转换

        方法名称 解析示例值 说明 自定义函数
        ToString CAST( a."xx" AS VARCHAR(255) ) 转换 VARCHAR
        ToDateTime TO_TIMESTAMP( a."xx" ,'yyyy-MM-dd hh:mi:ss.ff') 转换 DATETIME
        ToDecimal CAST( a."xx" AS DECIMAL(10,6) ) 转换 DECIMAL
        ToDouble CAST( a."xx" AS NUMBER ) 转换 NUMBER
        ToSingle CAST( a."xx" AS FLOAT ) 转换 FLOAT
        ToInt32 CAST( a."xx" AS INT ) 转换 INT
        ToInt64 CAST( a."xx" AS NUMBER ) 转换 NUMBER
        ToBoolean CAST( a."xx" AS CHAR(1) ) 转换 CHAR
        ToChar CAST( a."xx" AS CHAR(2) ) 转换 CHAR
      • 聚合函数

        方法名称 解析示例值 说明 自定义函数
        Max MAX( a."xx" ) 最大值
        Min MIN( a."xx" ) 最小值
        Count COUNT( a."xx" ) 计数
        Sum SUM( a."xx" ) 合计
        Avg AVG( a."xx" ) 平均
      • 数学函数

        方法名称 解析示例值 说明 自定义函数
        Abs ABS( a."xx" ) 绝对值
        Round ROUND( a."xx" ,2 ) 四舍五入
      • 字符串函数

        方法名称 解析示例值 说明 自定义函数
        StartsWith LIKE CONCAT( 'xx','%' ) 左模糊
        EndsWith LIKE CONCAT( '%','xx' ) 右模糊
        Contains LIKE CONCAT( '%','xx','%' ) 全模糊
        SubString SUBSTRING( 'xxxxxx' ,1,3) 截取
        Replace REPLACE( 'xxx','x','y') 替换
        Length LENGTH( 'xxx' ) 长度
        TrimStart LTRIM( ' xx ' ) 修剪起始空格
        TrimEnd RTRIM( ' xx ' ) 修剪末尾空格
        ToUpper UPPER( 'xx' ) 大写
        ToLower LOWER( 'xx' ) 小写
        Concat CONCAT(a."xx1",a."xx2") 字符串拼接
        Operation ”CreateTime“ >= @Now_1 日期、数值、字符串范围比较
      • 日期函数

        方法名称 解析示例值 说明 自定义函数
        Year EXTRACT( YEAR FROM a."xx" ) 获取年份
        Month EXTRACT( MONTH FROM a."xx" ) 获取月份
        Day EXTRACT( DAY FROM a."xx" ) 获取天数
      • 其它函数

        方法名称 解析示例值 说明 自定义函数
        Equals p."ProductCode" = '123' 比较
        Nvl NVL( a."xx",0 ) 空,默认
        Case CASE case
        When WHEN when
        Then THEN then
        Else ELSE else
        End END end
    • PostgreSql

      • 类型转换

        方法名称 解析示例值 说明 自定义函数
        ToString a."xx"::VARCHAR(255) 转换 VARCHAR
        ToDateTime a."xx"::TIMESTAMP 转换 TIMESTAMP
        ToDecimal a."xx"::DECIMAL(10,6) 转换 DECIMAL
        ToDouble a."xx"::NUMERIC(10,6) 转换 NUMERIC
        ToSingle a."xx"::REAL 转换 REAL
        ToInt32 a."xx"::INTEGER 转换 INT
        ToInt64 a."xx"::BIGINT 转换 BIGINT
        ToBoolean a."xx"::BOOLEAN 转换 BOOLEAN
        ToChar a."xx"::CHAR(2) 转换 CHAR
      • 聚合函数

        方法名称 解析示例值 说明 自定义函数
        Max MAX( a."xx" ) 最大值
        Min MIN( a."xx" ) 最小值
        Count COUNT( a."xx" ) 计数
        Sum SUM( a."xx" ) 合计
        Avg AVG( a."xx" ) 平均
      • 数学函数

        方法名称 解析示例值 说明 自定义函数
        Abs ABS( a."xx" ) 绝对值
        Round ROUND( a."xx" ,2 ) 四舍五入
      • 字符串函数

        方法名称 解析示例值 说明 自定义函数
        StartsWith LIKE CONCAT( '%','xx' ) 左模糊
        EndsWith LIKE CONCAT( 'xx','%' ) 右模糊
        Contains LIKE CONCAT( '%','xx','%' ) 全模糊
        SubString SUBSTRING( 'xxxxxx' ,1,3 ) 截取
        Replace REPLACE( 'xxx','x','y' ) 替换
        Length LENGTH( 'xxx' ) 长度
        Trim TRIM( ' xx ' ) 修剪空格
        TrimStart LTRIM( ' xx ' ) 修剪起始空格
        TrimEnd RTRIM( ' xx ' ) 修剪末尾空格
        ToUpper UPPER( 'xx' ) 大写
        ToLower LOWER( 'xx' ) 小写
        Concat CONCAT(a."xx1",a."xx2") 字符串拼接
        Operation ”CreateTime“ >= @Now_1 日期、数值、字符串范围比较
      • 日期函数

        方法名称 解析示例值 说明 自定义函数
        AddYears a."xx" + INTERVAL '1 YEAR' 添加年份
        AddMonths a."xx" + INTERVAL '1 MONTH' 添加月份
        AddDays a."xx" + INTERVAL '1 DAY' 添加天数
        AddHours a."xx" + INTERVAL '1 HOUR' 添加时
        AddMinutes a."xx" + INTERVAL '1 MINUTE' 添加分
        AddSeconds a."xx" + INTERVAL '1 SECOND' 添加秒
        AddMilliseconds a."xx" + INTERVAL '1 MINUTE_SECOND' 添加毫秒
        Year YEAR( a."xx" ) 获取年份
        Month MONTH( a."xx" ) 获取月份
        Day DAY( a."xx" ) 获取天数
      • 查询函数

        方法名称 解析示例值 说明 自定义函数
        In IN ( a."xx" ,'x1','x2','x3' ) In查询
        NotIn NOT IN ( a."xx" ,'x1','x2','x3' ) Not In查询
      • 其它函数

        方法名称 解析示例值 说明 自定义函数
        Equals p.”ProductCode“ = '123' 比较
        Case CASE case
        When WHEN when
        Then THEN then
        Else ELSE else
        End END end
    • Sqlite

      • 类型转换

        方法名称 解析示例值 说明 自定义函数
        ToString CAST(a.[xx] AS TEXT ) 转换 TEXT
        ToDateTime DATETIME( a.[xx] ) 转换 DateTime
        ToDecimal CAST(a.[xx] AS DECIMAL(10,6) ) 转换 DECIMAL
        ToDouble CAST(a.[xx] AS NUMERIC(10,6) ) 转换 NUMERIC
        ToSingle CAST(a.[xx] AS FLOAT ) 转换 FLOAT
        ToInt32 CAST(a.[xx] AS INTEGER ) 转换 INTEGER
        ToInt64 CAST(a.[xx] AS BIGINT ) 转换 BIGINT
        ToBoolean CAST(a.[xx] AS CHAR(1) ) 转换 CHAR
        ToChar CAST(a.[xx] AS CHAR(2) ) 转换 CHAR
      • 聚合函数

        方法名称 解析示例值 说明 自定义函数
        Max MAX( a.[xx] ) 最大值
        Min MIN( a.[xx] ) 最小值
        Count COUNT( a.[xx] ) 计数
        Sum SUM( a.[xx] ) 合计
        Avg AVG( a.[xx] ) 平均
      • 数学函数

        方法名称 解析示例值 说明 自定义函数
        Abs ABS( a.[xx] ) 绝对值
        Round ROUND( a.[xx] ,2 ) 四舍五入
      • 字符串函数

        方法名称 解析示例值 说明 自定义函数
        StartsWith LIKE 'xx'||'%' 左模糊
        EndsWith LIKE '%'||'xx'
        Contains LIKE '%'||'xx'||'%' 全模糊
        SubString SUBSTRING( 'xxxxxx' ,1,3 ) 截取
        Replace REPLACE( 'xxx','x','y' ) 替换
        Length LENGTH( 'xxx' ) 长度
        Trim TRIM( ' xx ' ) 修剪空格
        TrimStart LTRIM( ' xx ' ) 修剪起始空格
        TrimEnd RTRIM( ' xx ' ) 修剪末尾空格
        ToUpper UPPER( 'xx' ) 大写
        ToLower LOWER( 'xx' ) 小写
        Operation [CreateTime] >= @Now_1 日期、数值、字符串范围比较
      • 日期函数

        方法名称 解析示例值 说明 自定义函数
        AddYears DATETIME( a.[xx],'1 YEAR' ) 添加年份
        AddMonths DATETIME( a.[xx],'1 MONTH' ) 添加月份
        AddDays DATETIME( a.[xx],'1 DAY' ) 添加天数
        AddHours DATETIME( a.[xx],'1 HOUR' ) 添加时
        AddMinutes DATETIME( a.[xx],'1 MINUTE' ) 添加分
        AddSeconds DATETIME( a.[xx],'1 SECOND' ) 添加秒
        AddMilliseconds DATETIME( a.[xx],'1 YEAR' ) 添加毫秒
        Year STRFTIME( '%Y', a.[xx] ) 获取年份
        Month STRFTIME( '%m', a.[xx] ) 获取月份
        Day STRFTIME( '%j', a.[xx] ) 获取天数
      • 其它函数

        方法名称 解析示例值 说明 自定义函数
        Equals p.”ProductCode“ = '123' 比较
        Case CASE case
        When WHEN when
        Then THEN then
        Else ELSE else
        End END end
  • 添加自定义函数解析

    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. [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  12. public int ProductId { get; set; }
  13. /// <summary>
  14. /// 产品编号
  15. /// </summary>
  16. [Column("ProductCode")]//不标记默认取当前属性名称
  17. public string ProductCode { get; set; }
  18. /// <summary>
  19. /// 自定义1
  20. /// </summary>
  21. [NotMapped]
  22. public string Custom1 { get; set; }
  23. /// <summary>
  24. /// 自定义2
  25. /// </summary>
  26. [Column(TypeName="Json")]//类型标记为Json格式对象 匿名对象属性以及字典值类型 IsClass&&!type.Equals(typeof(string)) 将自动序列化成Json格式
  27. public Category Custom2 { get; set; }
  28. }
十三、原生Ado
  1. // 原始起步
  2. // var conn = db.Ado.DbProviderFactory.CreateConnection();
  3. // var cmd = conn.CreateCommand();
  4. // 封装的方法分别以Execute和Create开头以及预处理 PrepareCommand 方法
  5. // 该方法可以自动帮你处理执行的预操作,主要作用是代码复用。
  6. // 当有非常复杂的查询 ORM不能满足需求的时候可以使用原生Ado满足业务需求
  7. // 构建数据集核心扩展方法 分别有 FirstBuild 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.AddUnitOfWork();
    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. }
十五、大数据导入
  • 批复制 仅支持SqlServer Oracle MySql PostgreSql

    1. var list = new List<Product>();
    2. for (int j = 1; j <= 100000; j++)
    3. {
    4. list.Add(new Product()
    5. {
    6. CategoryId = 1,
    7. ProductCode = $"测试编号_{Timestamp.CurrentTimestampSeconds()}_{j}",
    8. ProductName = $"测试名称_{Timestamp.CurrentTimestampSeconds()}_{j}",
    9. CreateTime = DateTime.Now,
    10. Custom1 = $"测试自定义1_{Timestamp.CurrentTimestampSeconds()}_{j}",
    11. Custom2 = $"测试自定义2_{Timestamp.CurrentTimestampSeconds()}_{j}",
    12. Custom3 = $"测试自定义3_{Timestamp.CurrentTimestampSeconds()}_{j}",
    13. Custom4 = $"测试自定义4_{Timestamp.CurrentTimestampSeconds()}_{j}",
    14. Custom5 = $"测试自定义5_{Timestamp.CurrentTimestampSeconds()}_{j}",
    15. Custom6 = $"测试自定义6_{Timestamp.CurrentTimestampSeconds()}_{j}",
    16. Custom7 = $"测试自定义7_{Timestamp.CurrentTimestampSeconds()}_{j}",
    17. Custom8 = $"测试自定义8_{Timestamp.CurrentTimestampSeconds()}_{j}",
    18. Custom9 = $"测试自定义9_{Timestamp.CurrentTimestampSeconds()}_{j}",
    19. Custom10 = $"测试自定义10_{Timestamp.CurrentTimestampSeconds()}_{j}",
    20. Custom11 = $"测试自定义11_{Timestamp.CurrentTimestampSeconds()}_{j}",
    21. Custom12 = $"测试自定义12_{Timestamp.CurrentTimestampSeconds()}_{j}",
    22. });
    23. }
    24. db.Fast<Product>().BulkCopy(list);

基于.net6.0 Fast.ORM 已全面支持AOT编译 所有Api均测试通过的更多相关文章

  1. 如何在Net6.0里配置多版本支持并支持注释说明的Swagger

    一.前言 现在已经进入了微服务的开发时代了,在这个时代,如果有人问你什么是微服务,你说不知道,就有点太丢人了,别人会有异样的眼光看你,俗话说:唾液淹死人.没办法,我们只能去学习新的东西.一提到微服务, ...

  2. Azure DevOps(一)基于 Net6.0 的 WPF 程序如何进行持续集成、持续编译

    一,引言 我们是否正在为如何快速的编译.部署客户端应用程序而烦恼?这也是博主最近遇到的问题.目前博主所在公司主要做项目级的定制化开发,多以 C/S 架构的 WPF 程序为主,每次到了协助开发团队给实施 ...

  3. VB6.0对鼠标滚轮不支持的解决方法[转]已经测试work

    今天要修改一个老DLL文件,安装了vb6,用起来很不爽. VB6编辑器 和 VBA编辑器 (Office 中的VB编辑器)都不支持鼠标滚动. 但 MS 已经提供了补丁http://download.m ...

  4. 基于AFNetworking3.0网络封装

    概述 对于开发人员来说,学习网络层知识是必备的,任何一款App的开发,都需要到网络请求接口.很多朋友都还在使用原生的NSURLConnection一行一行地写,代码到处是,这样维护起来更困难了. 对于 ...

  5. 使用JMeter测试.Net5.0,.Net6.0框架下无数据处理的并发情况

    1.   安装JMeter及使用 1.1下载JMeter 登录官方网站找到下载链接进行下载:https://jmeter.apache.org/download_jmeter.cgi 1.2配置环境变 ...

  6. 并发编程概述 委托(delegate) 事件(event) .net core 2.0 event bus 一个简单的基于内存事件总线实现 .net core 基于NPOI 的excel导出类,支持自定义导出哪些字段 基于Ace Admin 的菜单栏实现 第五节:SignalR大杂烩(与MVC融合、全局的几个配置、跨域的应用、C/S程序充当Client和Server)

    并发编程概述   前言 说实话,在我软件开发的头两年几乎不考虑并发编程,请求与响应把业务逻辑尽快完成一个星期的任务能两天完成绝不拖三天(剩下时间各种浪),根本不会考虑性能问题(能接受范围内).但随着工 ...

  7. 基于AFNetworking 3.0的取消已发出的网络请求

    一般情况下主动取消请求的需求不会太多 除非以下几种情况 1.比如电商应用为例 请求频繁,数据量大 2.对性能的要求比较高 3.网络环境比较差 当一个用户打开一个界面 看到的却是漫长的等待框 这时候用户 ...

  8. .NET微服务系统迁移至.NET6.0的故事

    本次迁移涉及的是公司内部一个业务子系统,该系统是一个多样化的应用,支撑着公司的多个业务方向.目前,该系统由40多个基于.NET的微服务应用构成,使用数千个CPU核心和数TB内存,在数百个Linux容器 ...

  9. Android基于Retrofit2.0 +RxJava 封装的超好用的RetrofitClient工具类(六)

    csdn :码小白 原文地址: http://blog.csdn.net/sk719887916/article/details/51958010 RetrofitClient 基于Retrofit2 ...

  10. 也来写写基于单表的Orm(使用Dapper)

    前言 这两天看园子里有个朋友写Dapper的拓展,想到自己之前也尝试用过,但不顺手,曾写过几个方法来完成自动的Insert操作.而对于Update.Delete.Select等,我一直对Diction ...

随机推荐

  1. tensorflow.js 多分类,机器学习区分企鹅种类

    前言: 在规则编码中,我们常常会遇到需要通过多种区间判断某种物品分类.比如二手物品的定价,尽管不是新品没有 SKU 但是基本的参数是少不了.想通过成色来区分某种物品,其实主要是确定一些参数.然后根据参 ...

  2. [jenkins]连接git仓库

    连接gitlab 在jenkins添加全局凭据,类型为"ssh username with private key",填写git用户名和ssh私钥信息(注意是git客户端所在机器的 ...

  3. 简述redis的单线程模式

    前言 在redis版本6之前,网络IO和键值对读写都是由一个线程来完成的.而redis的其他功能,比如持久化.异步删除.集群数据同步等,是由其他线程完成的. 为什么采用单线程 多线程有助于提升吞吐率( ...

  4. MySql之锁

    MySql之锁 一.全局锁 对整个数据库加锁 应用:数据库所有表备份 二.表级锁 1.表锁 分为两类: 表共享读锁read lock 表独占写锁write lock 2.元数据锁 避免DML语句和DD ...

  5. Apache-Log4j2-Rce漏洞复现

    最近最热门的无非是最近爆出的超大boss-Apache log4j2组件的rce漏洞.安全圈俗称'过年',漏洞影响范围之广,危害之大堪比当年的永恒之蓝.由于最近爆出,危害程度目前还正在不断扩大中.超多 ...

  6. Hugging News #0814: Llama 2 学习资源大汇总 🦙

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  7. 深入理解Linux内核——内存管理(2)

    提要:本系列文章主要参考MIT 6.828课程以及两本书籍<深入理解Linux内核> <深入Linux内核架构>对Linux内核内容进行总结. 内存管理的实现覆盖了多个领域: ...

  8. Gopher进阶神器:拥抱刻意练习,从新手到大师。

    发现一个非常友好的工具,帮助我们回顾练习过程,设定目标,并提供丰富多样的Gopher主题练习题. 刻意练习:从新手到大师. Carol 心理学家 Carol Dweck 做过一个实验,她找了一些十岁的 ...

  9. Redis从入门到放弃(12):pipeline管道技术

    1.引言 在现代应用程序中,高性能和低延迟是至关重要的因素.而在处理大规模数据操作时,Redis作为一种快速.可靠的内存数据库,成为了许多开发人员的首选. 在Redis中,每个操作都需要与服务器进行往 ...

  10. Content Security Policy(CSP)应用及说明

    什么是CSP CSP全称Content Security Policy ,可以直接翻译为内容安全策略,说白了,就是为了页面内容安全而制定的一系列防护策略. 通过CSP所约束的的规责指定可信的内容来源( ...