首頁>上市公司 > 正文

      今日熱聞!自研ORM (匠心之作)

      2023-06-30 15:04:36    出處:博客園
      Fast Framework

      作者 Mr-zhong


      (資料圖片僅供參考)

      代碼改變世界....

      一、前言

      Fast Framework 基于NET6.0 封裝的輕量級 ORM 框架 支持多種數(shù)據(jù)庫 SqlServer Oracle MySql PostgreSql Sqlite

      優(yōu)點: 體積小、可動態(tài)切換不同實現(xiàn)類庫、原生支持微軟特性、流暢API、使用簡單、性能高、模型數(shù)據(jù)綁定采用 委托、強大的表達式解析、支持多種子查詢可實現(xiàn)較為復(fù)雜查詢、源代碼可讀性強。

      缺點:目前僅支持Db Frist Code Frist 后續(xù)迭代。

      開源地址:https://github.com/China-Mr-zhong/Fast-Framework (唯一)

      框架經(jīng)受住了生產(chǎn)項目的考驗,穩(wěn)定運行中。

      二、項目明細
      名稱說明
      Fast.Framework框架主項目
      Fast.Framework.Logging基于微軟接口實現(xiàn)的文件日志(非必要可不引用)
      Fast.Framework.Test控制臺測試項目
      Fast.Framework.UnitTest單元測試項目
      Fast.Framework.Web.TestWeb測試項目
      三、核心對象

      Ado

      IAdo ado = new AdoProvider(new DbOptions()                {                    DbId = "1",                    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;"                });

      DbContext 支持多租戶 支持切換不同Ado實現(xiàn)類庫 設(shè)置 ProviderName和FactoryName 即可

      IDbContext db = new DbContext(new List() {                new DbOptions()                {                    DbId = "1",                    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;"                }});

      DbOptions Json文件配置格式

      "DbOptions": [    {      "DbId": 1,      "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=120;"    }]

      主從分離(讀寫分離)配置

      "DbOptions": [    {      "DbId": 2,      "DbType": "MySQL",      "IsDefault": true,      "ProviderName": "MySqlConnector",      "FactoryName": "MySqlConnector.MySqlConnectorFactory,MySqlConnector",      "ConnectionStrings": "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",      "UseMasterSlaveSeparation": true,//使用主從分離 注意所有事務(wù)將強制走主庫      "SlaveItems": [        {          "Weight": 1,//注意多個從庫 必須配置權(quán)重且總權(quán)重>從庫數(shù)          "ConnectionStrings": "server=localhost;database=Test1;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",          "Description": "從庫連接配置"        },        {          "Weight": 2,          "ConnectionStrings": "server=localhost;database=Test2;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;AllowLoadLocalInfile=true;",          "Description": "從庫連接配置"        }      ],      "Description": "主庫連接配置"    }  ]

      Asp.net Core 依賴注入

      // 注冊服務(wù) var builder = WebApplication.CreateBuilder(args);// 添加數(shù)據(jù)庫上下文builder.Services.AddFastDbContext();// 從Json配置文件加載數(shù)據(jù)庫選項builder.Services.Configure>(builder.Configuration.GetSection("DbOptions"));// 產(chǎn)品服務(wù)類 通過構(gòu)造方法注入public class ProductService{    ///     /// 數(shù)據(jù)庫    ///     private readonly IDbContext db;    ///     /// 構(gòu)造方法    ///     /// 數(shù)據(jù)庫    public ProductService(IDbContext db)    {        this.db = db;    }}
      四、插入

      實體對象插入

      var product = new Product()            {                ProductCode = "1001",                ProductName = "測試商品1"            };            var result = db.Insert(product).Exceute();            Console.WriteLine($"實體對象插入 受影響行數(shù) {result}");

      實體對象插入并返回自增ID 僅支持 SQLServer MySQL SQLite

      var product = new Product()            {                ProductCode = "1001",                ProductName = "測試產(chǎn)品1"            };            var result = db.Insert(product).ExceuteReturnIdentity();            Console.WriteLine($"實體對象插入 返回自增ID {result}");

      實體對象列表插入

      var list = new List();            for (int i = 0; i < 2100; i++)            {                list.Add(new Product()                {                    ProductCode = $"編號{i + 1}",                    ProductName = $"名稱{i + 1}"                });            }            var result = db.Insert(list).Exceute();            Console.WriteLine($"實體對象列表插入 受影響行數(shù) {result}");

      匿名對象插入

      var obj = new            {                ProductCode = "1001",                ProductName = "測試商品1"            };            //注意:需要使用As方法顯示指定表名稱            var result = db.Insert(obj).As("Product").Exceute();            Console.WriteLine($"匿名對象插入 受影響行數(shù) {result}");

      匿名對象列表插入

      var list = new List();            for (int i = 0; i < 2100; i++)            {                list.Add(new                {                    ProductCode = $"編號{i + 1}",                    ProductName = $"名稱{i + 1}"                });            }            //注意:需要使用As方法顯示指定表名稱            var result = db.Insert(list).As("Product").Exceute();            Console.WriteLine($"匿名對象列表插入 受影響行數(shù) {result}");

      字典插入

      var product = new Dictionary()            {                {"ProductCode","1001"},                { "ProductName","測試商品1"}            };            var result = db.Insert(product).As("Product").Exceute();            Console.WriteLine($"字典插入 受影響行數(shù) {result}");

      字典列表插入

      var list = new List>();            for (int i = 0; i < 2100; i++)            {                list.Add(new Dictionary()                {                    {"ProductCode","1001"},                    { "ProductName","測試商品1"}                 });            }            var result = db.Insert(list).As("Product").Exceute();            Console.WriteLine($"字典列表插入 受影響行數(shù) {result}");
      五、刪除

      實體對象刪除

      var product = new Product()            {                ProductId = 1,                ProductCode = "1001",                ProductName = "測試商品1"            };            //注意:必須標(biāo)記KeyAuttribute特性 否則將拋出異常            var result = db.Delete(product).Exceute();            Console.WriteLine($"實體刪除 受影響行數(shù) {result}");

      無條件刪除

      var result = db.Delete().Exceute();            Console.WriteLine($"無條件刪除 受影響行數(shù) {result}");

      表達式刪除

      var result = await db.Delete().Where(w => w.ProductId == 1).ExceuteAsync();            Console.WriteLine($"條件刪除 受影響行數(shù) {result}");

      特殊刪除

      //特殊用法 如需單個條件或多個可搭配 WhereColumn或WhereColumns方法            var result = await db.Delete().As("Product").ExceuteAsync();            Console.WriteLine($"無實體刪除 受影響行數(shù) {result}");六、更新

      實體對象更新

      var product = new Product()            {                ProductId = 1,                ProductCode = "1001",                ProductName = "測試商品1"            };            //注意:標(biāo)記KeyAuttribute特性屬性或使用Where條件,為了安全起見全表更新將必須使用Where方法            var result = db.Update(product).Exceute();            Console.WriteLine($"對象更新 受影響行數(shù) {result}");

      指定列更新

      var result = db.Update(new Product() { ProductCode = "1001", ProductName = "1002" }).Columns(c=> new { c.ProductCode , c.ProductName }).Exceute();// 推薦使用表達式 c=>new {} 好處更改屬性名稱可以同步修改

      忽略列更新

      var result = db.Update(new Product() { ProductCode = "1001", ProductName = "1002" }).IgnoreColumns(c=> new { c.Custom1 }).Exceute();            // 同上使用方法一樣

      實體對象列表更新

      var list = new List();            for (int i = 0; i < 2022; i++)            {                list.Add(new Product()                {                    ProductCode = $"編號{i + 1}",                    ProductName = $"名稱{i + 1}"                });            }            //注意:標(biāo)記KeyAuttribute特性屬性或使用WhereColumns方法指定更新條件列            var result = db.Update(list).Exceute();            Console.WriteLine($"對象列表更新 受影響行數(shù) {result}");

      匿名對象更新

      var obj = new            {                ProductId = 1,                ProductCode = "1001",                ProductName = "測試商品1"            };            //注意:需要顯示指定表名稱 以及更新條件 使用 Where或者WhereColumns方法均可            var result = db.Update(obj).As("product").WhereColumns("ProductId").Exceute();            Console.WriteLine($"匿名對象更新 受影響行數(shù) {result}");

      匿名對象列表更新

      var list = new List();            for (int i = 0; i < 2022; i++)            {                list.Add(new                {                    ProductId = i + 1,                    ProductCode = $"編號{i + 1}",                    ProductName = $"名稱{i + 1}"                });            }            //由于是匿名對象需要顯示指定表名稱,使用WhereColumns方法指定更新條件列            var result = db.Update(list).As("Product").WhereColumns("ProductId").Exceute();            Console.WriteLine($"匿名對象列表更新 受影響行數(shù) {result}");

      字典更新

      var product = new Dictionary()            {                { "ProductId",1},                {"ProductCode","1001"},                { "ProductName","測試商品1"}            };            var result = db.Update(product).As("Product").WhereColumns("ProductId").Exceute();            Console.WriteLine($"字典更新 受影響行數(shù) {result}");

      字典列表更新

      var list = new List>();            for (int i = 0; i < 2022; i++)            {                list.Add(new Dictionary()                {                    { "ProductId",i+1},                    {"ProductCode",$"更新編號:{i+1}"},                    { "ProductName",$"更新商品:{i + 1}"}                });            }            var result = db.Update(list).As("Product").WhereColumns("ProductId").Exceute();            Console.WriteLine($"字典列表更新 受影響行數(shù) {result}");

      指定條件更新

      var product = new Product()            {                ProductId = 1,                ProductCode = "1001",                ProductName = "測試商品1"            };            var result = db.Update(product).Where(p => p.ProductId == 100).Exceute();            Console.WriteLine($"表達式更新 受影響行數(shù) {result}");

      并發(fā)更新 樂觀鎖-版本控制

      //注意:僅支持非列表更新 版本列數(shù)據(jù)類型僅支持 object、string、Guid 時間類型存在精度丟失所以不做支持var obj = db.Query().Where(w => w.ProductId == 1).Frist();                obj.Custom1 = "測試版本控制修改";//參數(shù)為 true 更新失敗將拋出異常                var result = db.Update(obj).ExceuteWithOptLock(true);
      七、查詢

      單一查詢

      var data = db.Query().First();

      列表查詢

      var data = db.Query().ToList();

      返回單個字典

      var data = db.Query().ToDictionary();

      返回字典列表

      var data = db.Query().ToDictionaryList();

      分頁查詢

      //分頁查詢不返回總數(shù)            var data = db.Query().ToPageList(1,100);            //分頁查詢返回總數(shù)var total = 0;//定義總數(shù)變量var data = db.Query().ToPageList(1, 1, ref total);            Console.WriteLine($"總數(shù):{total}");

      計數(shù)查詢

      var data = db.Query().Count();

      任何查詢

      var data = db.Query().Any();

      條件查詢

      var data = db.Query().Where(w => w.ProductId == 1).ToList;

      Like 查詢

      var data = db.Query().Where(w => w.ProductName.StartsWith("左模糊") || w.ProductName.EndsWith("右模糊") || w.ProductName.Contains("全模糊")).ToList();

      Not Like查詢

      var data = db.Query().Where(w => !w.ProductName.StartsWith("左模糊") || !w.ProductName.EndsWith("右模糊") || !w.ProductName.Contains("全模糊")).ToList();

      Select查詢 (選擇字段)

      var data = db.Query().Select(s => new            {                s.ProductId,                s.ProductName            }).ToList();

      Select查詢 (Case When)

      var data = db.Query().Select(s => new                {                    CaseTest1 = SqlFunc.Case(s.Custom1).When("1").Then("xx1").When("2").Then("xx2").Else("xx3").End(),                    CaseTest2 = SqlFunc.CaseWhen(s.Custom1 == "1").Then("xx1").When(s.Custom1 == "2").Then("xx2").Else("xx3").End()                }).ToList();

      分組查詢

      var data = db.Query().GroupBy(s => new            {                s.ProductId,                s.ProductName            }).ToList();

      分組聚合查詢

      var sql = db.Query().InnerJoin((a, b) => a.OrderId == b.OrderId).GroupBy((a, b) => new            {                a.OrderCode            }).Select((a, b) => new            {                a.OrderCode,                Sum_Qty = SqlFunc.Sum(b.Qty)//支持嵌套            }).ToList();

      排序查詢

      var data = db.Query().OrderBy(s => new            {                s.CreateTime            }).ToList();            //這是多個字段排序使用方法 還有其它重載方法

      Having查詢

      var data = db.Query().GroupBy(s => new            {                s.ProductId,                s.ProductName            }).Having(s => SqlFunc.Count(s.ProductId) > 1).ToList();            //必須先使用GroupBy方法 懂得都懂

      聯(lián)表查詢

      var data = db.Query().LeftJoin((a, b) => a.ProductId == b.ProductId).ToList();            // 右連接 RightJoin 內(nèi)連接 InnerJoin 全連接 FullJoin

      聯(lián)合查詢

      var query1 = db.Query();            var query2 = db.Query();            db.Union(query1, query2);//聯(lián)合            db.UnionAll(query1, query2);//全聯(lián)合            //執(zhí)行查詢調(diào)用Toxx方法

      導(dǎo)航查詢 (支持無限層級)

      ///                 /// 類別                ///                 public class Category                {                    ///                     /// 類別ID                    ///                     [Key]                    public int CategoryId { get; set; }                                    ///                     /// 類別名稱                    ///                     public string CategoryName { get; set; }                                    ///                     /// 產(chǎn)品 Navigate MainName和ChildName 可不顯示指定,會自動查找主鍵匹配或ID為結(jié)尾的屬性                    ///                     [Navigate(MainName = nameof(CategoryId), ChildName = nameof(Product.CategoryId))]                    public IEnumerable Products { get; set; }                                }                var data = db.Query()                    .Include(i => i.Products)                    .ThenInclude(i => i.Category)                    .ToList();

      查詢并插入 僅支持同實例的數(shù)據(jù)庫 跨庫 個人還是建議 用事務(wù)分開寫查詢和插入

      //方式1                var result1 = db.Query().Where(w => w.ProductId == 1489087).Select(s => new                {                    s.ProductCode,                    s.ProductName                }).Insert(p => new                {                    p.ProductCode,                    p.ProductName                });                //方式2                var result2 = db.Query().Where(w => w.ProductId == 1489087).Select(s => new                {                    s.ProductCode,                    s.ProductName                }).Insert("表名稱 同實例不同庫 可以使用 db.數(shù)據(jù)庫名稱.表名稱 ", "列名稱1", "列名稱2");                //方式3 需要注意同方式2 一樣                var result3 = db.Query().Where(w => w.ProductId == 1489087).Select(s => new                {                    s.ProductCode,                    s.ProductName                }).Insert("表名稱 同實例不同庫 可以使用 db.數(shù)據(jù)庫名稱.表名稱 ", new List() { "列名稱1" });

      In查詢

      var data1 = db.Query().Where(w => new List(){"1001", "1002"}.Contains(w.ProductCode)).ToList();

      Select嵌套查詢和子查詢

      var data1 = db.Query().Select(s => new                {                    XX = db.Query().Select(s => 1).First()//需調(diào)用返回結(jié)果的方法 否則無法解析                }).First();//進價用法,下面示例方法的重載均支持                var query = db.Query().Select(s => new                {                    WithAttr_First = db.QueryWithAttr().First(),                    WithAttr_FirstAsync = db.QueryWithAttr().FirstAsync(),                    WithAttr_ToList = db.QueryWithAttr().ToList(),                    WithAttr_ToListAsync = db.QueryWithAttr().ToListAsync(),                    First_1 = db.Query().Select(s => 1).First(),//解析成Sql                    First = db.Query().First(),                    FirstAsync = db.Query().FirstAsync(),                    ToArray = db.Query().ToArray(),                    ToArrayAsync = db.Query().ToArrayAsync(),                    ToList = db.Query().ToList(),                    ToListAsync = db.Query().ToListAsync(),                    ToPageList = db.Query().ToPageList(1, 10),                    ToPageListAsync = db.Query().ToPageListAsync(1, 10),                    ToPageList_Count = db.Query().ToPageList(1, 10, ref count),                    ToPageListAsync_Count = db.Query().ToPageListAsync(1, 10, refAsync),                    ToDictionary = db.Query().ToDictionary(),                    ToDictionaryAsync = db.Query().ToDictionaryAsync(),                    ToDictionaryList = db.Query().ToDictionaryList(),                    ToDictionaryListAsync = db.Query().ToDictionaryListAsync(),                    ToDictionaryPageList = db.Query().ToDictionaryPageList(1, 10),                    ToDictionaryPageListAsync = db.Query().ToDictionaryPageListAsync(1, 10),                    ToDictionaryPageList_Count = db.Query().ToDictionaryPageList(1, 10, ref count),                    ToDictionaryPageListAsync_Count = db.Query().ToDictionaryPageListAsync(1, 10, refAsync),                    ToDataTable = db.Query().ToDataTable(),                    ToDataTableAsync = db.Query().ToDataTableAsync(),                    ObjToJson = db.Query().ObjToJson(),                    ObjToJsonAsync = db.Query().ObjToJsonAsync(),                    ObjListToJson = db.Query().ObjListToJson(),                    ObjListToJsonAsync = db.Query().ObjListToJsonAsync(),                    Max = db.Query().Max(a => a.CategoryId),//解析成Sql                    MaxAsync = db.Query().MaxAsync(a => a.CategoryId),                    Min = db.Query().Min(a => a.CategoryId),//解析成Sql                    MinAsync = db.Query().MinAsync(a => a.CategoryId),                    Count = db.Query().Count(),//解析成Sql                    CountAsync = db.Query().CountAsync(),                    Sum = db.Query().Sum(s => s.CategoryId),//解析成Sql                    SumAsync = db.Query().SumAsync(s => s.CategoryId),                    Avg = db.Query().Avg(s => s.CategoryId),//解析成Sql                    AvgAsync = db.Query().AvgAsync(s => s.CategoryId)                });var data2= query.First();

      From子查詢

      var subQuery = db.Query();                var data = db.Query(subQuery).OrderBy(o => o.ProductCode).ToList();

      Join子查詢

      var subQuery = db.Query();                var data = db.Query().InnerJoin(subQuery, (a, b) => a.ProductId == b.ProductId).ToList();

      Include查詢

      // 聯(lián)表條件 默認優(yōu)先匹配主鍵 其次帶有ID結(jié)尾的名稱                var data = db.Query().Include(i => i.Products).ToList();

      Exists查詢

      var data = db.Query()                    .Where(w => db.Query().WhereIF(!string.IsNullOrWhiteSpace("測試"), a => a.ProductId == 1).Select(s => 1).Any())                    .Select(s => new                    {                        s.ProductId,                        s.ProductCode                    }).ToList();

      查詢綁定字段(注意 字段必須是公開的,否則綁定外部無法訪問,沒有意義)

      //當(dāng)某些字段需要參與計算并且不返回前端時推薦用字段綁定,無需從A實體轉(zhuǎn)換到B實體,強烈推薦此方式var data = db.Query().Select(s => new Product()                {                    _xx = s.ProductName                }).First();
      八、Lambda表達式

      動態(tài)表達式 命名空間 Fast.Framework.Utils

      var ex = DynamicWhereExp.Create().AndIF(1 == 1, a => a.DeleteMark == true).Build();                var data = db.Query().Where(ex).ToList();

      Sql函數(shù) 自定義函數(shù) 需引入命名空間 Fast.Framework.Utils 使用SqlFunc類

      SqlServer

      類型轉(zhuǎn)換

      方法名稱解析示例值說明自定義函數(shù)
      ToStringCONVERT( VARCHAR(255),123)轉(zhuǎn)換 VARCHAR
      ToDateTimeCONVERT( DATETIME,‘2022-09-16’)轉(zhuǎn)換 DATETIME
      ToDecimalCONVERT( DECIMAL(10,6),‘123’)轉(zhuǎn)換 DECIMAL
      ToDoubleCONVERT( NUMERIC(10,6),‘123’)轉(zhuǎn)換 NUMERIC
      ToSingleCONVERT( FLOAT,‘123’)轉(zhuǎn)換 FLOAT
      ToInt32CONVERT( INT,‘123’)轉(zhuǎn)換 INT
      ToInt64CONVERT( BIGINT,‘123’)轉(zhuǎn)換 BIGINT
      ToBooleanCONVERT( BIT,‘1’)轉(zhuǎn)換 BIT
      ToCharCONVERT( CHAR(2),"x")轉(zhuǎn)換 CHAR

      聚合函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      MaxMAX( a.[xx] )最大值
      MinMIN( a.[xx] )最小值
      CountCOUNT( a.[xx] )計數(shù)
      SumSUM( a.[xx] )合計
      AvgAVG( a.[xx] )平均

      數(shù)學(xué)函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      AbsABS( a.[xx] )絕對值
      RoundROUND( a.[xx] ,2 )四舍五入

      字符串函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      StartsWithLIKE "xx"+‘%’左模糊
      EndsWithLIKE ‘%’+"xx"右模糊
      ContainsLIKE ‘%’+"xx"+‘%’全模糊
      SubStringSUBSTRING( "xxxxxx" ,1,3)截取
      ReplaceREPLACE( "xxx","x","y")替換
      LenLEN( "xxx" )長度
      TrimStartLTRIM( " xx " )修剪起始空格
      TrimEndRTRIM( " xx " )修剪末尾空格
      ToUpperUPPER( "xx" )大寫
      ToLowerLOWER( "xx" )小寫
      ConcatCONCAT(a.[xx1],a.[xx2])字符串拼接
      Operation[CreateTime] >= @Now_1日期、數(shù)值、字符串范圍比較

      日期函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      DateDiffDATEDIFF( DAY ,a.[xx],b.[xx])日期相差
      AddYearsDATEADD( YEAR,a.[xx],1 )添加年份
      AddMonthsDATEADD( MONTH,a.[xx],1 )添加月份
      AddDaysDATEADD( DAY,a.[xx],1 )添加天數(shù)
      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] )獲取天數(shù)

      其它函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      NewGuidNEWID()獲取GUID
      Equalsp.[ProductCode] = "123"比較
      IsNullISNULL(a.[xx],0)是否為空
      CaseCASEcase
      WhenWHENwhen
      ThenTHENthen
      ElseELSEelse
      EndENDend

      MySql

      類型轉(zhuǎn)換

      方法名稱解析示例值說明自定義函數(shù)
      ToStringCAST( a.`xx` AS CHAR(510) )轉(zhuǎn)換 CHAR(510)
      ToDateTimeCAST( a.`xx` AS DATETIME )轉(zhuǎn)換 DATETIME
      ToDecimalCAST( a.`xx` AS DECIMAL(10,6) )轉(zhuǎn)換 DECIMAL(10,6)
      ToDoubleCAST( a.`xx` AS DECIMAL(10,6) )轉(zhuǎn)換 DECIMAL(10,6)
      ToInt32CAST( a.`xx` AS DECIMAL(10) )轉(zhuǎn)換 DECIMAL(10)
      ToInt64CAST( a.`xx` AS DECIMAL(19) )轉(zhuǎn)換 DECIMAL(19)
      ToBooleanCAST( a.`xx` AS UNSIGNED )轉(zhuǎn)換 UNSIGNED
      ToCharCAST( a.`xx` AS CHAR(2) )轉(zhuǎn)換 CHAR(2)

      聚合函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      MaxMAX( a.`xx` )最大值
      MinMIN( a.`xx` )最小值
      CountCOUNT( a.`xx` )計數(shù)
      SumSUM( a.`xx` )合計
      AvgAVG( a.`xx` )平均

      數(shù)學(xué)函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      AbsABS( a.`xx` )絕對值
      RoundROUND( a.`xx` ,2 )四舍五入

      字符串函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      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`)字符串拼接
      Operation`CreateTime` >= @Now_1日期、數(shù)值、字符串范圍比較

      日期函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      DateDiffDATEDIFF( a.`xx`,b.`xx` )日期相差 返回相差天數(shù)
      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 )添加天數(shù)
      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` )獲取天數(shù)

      其它函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      NewGuidUUID()獲取GUID
      Equalsp.`ProductCode` = "123"比較
      IfNullIFNULL( a.`xx`,0 )如果為空
      CaseCASEcase
      WhenWHENwhen
      ThenTHENthen
      ElseELSEelse
      EndENDend

      Oracle

      類型轉(zhuǎn)換

      方法名稱解析示例值說明自定義函數(shù)
      ToStringCAST( a."xx" AS VARCHAR(255) )轉(zhuǎn)換 VARCHAR
      ToDateTimeTO_TIMESTAMP( a."xx" ,"yyyy-MM-dd hh:mi:ss.ff")轉(zhuǎn)換 DATETIME
      ToDecimalCAST( a."xx" AS DECIMAL(10,6) )轉(zhuǎn)換 DECIMAL
      ToDoubleCAST( a."xx" AS NUMBER )轉(zhuǎn)換 NUMBER
      ToSingleCAST( a."xx" AS FLOAT )轉(zhuǎn)換 FLOAT
      ToInt32CAST( a."xx" AS INT )轉(zhuǎn)換 INT
      ToInt64CAST( a."xx" AS NUMBER )轉(zhuǎn)換 NUMBER
      ToBooleanCAST( a."xx" AS CHAR(1) )轉(zhuǎn)換 CHAR
      ToCharCAST( a."xx" AS CHAR(2) )轉(zhuǎn)換 CHAR

      聚合函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      MaxMAX( a."xx" )最大值
      MinMIN( a."xx" )最小值
      CountCOUNT( a."xx" )計數(shù)
      SumSUM( a."xx" )合計
      AvgAVG( a."xx" )平均

      數(shù)學(xué)函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      AbsABS( a."xx" )絕對值
      RoundROUND( a."xx" ,2 )四舍五入

      字符串函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      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")字符串拼接
      Operation”CreateTime“ >= @Now_1日期、數(shù)值、字符串范圍比較

      日期函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      YearEXTRACT( YEAR FROM a."xx" )獲取年份
      MonthEXTRACT( MONTH FROM a."xx" )獲取月份
      DayEXTRACT( DAY FROM a."xx" )獲取天數(shù)

      其它函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      Equalsp."ProductCode" = "123"比較
      NvlNVL( a."xx",0 )空,默認
      CaseCASEcase
      WhenWHENwhen
      ThenTHENthen
      ElseELSEelse
      EndENDend

      PostgreSql

      類型轉(zhuǎn)換

      方法名稱解析示例值說明自定義函數(shù)
      ToStringa."xx"::VARCHAR(255)轉(zhuǎn)換 VARCHAR
      ToDateTimea."xx"::TIMESTAMP轉(zhuǎn)換 TIMESTAMP
      ToDecimala."xx"::DECIMAL(10,6)轉(zhuǎn)換 DECIMAL
      ToDoublea."xx"::NUMERIC(10,6)轉(zhuǎn)換 NUMERIC
      ToSinglea."xx"::REAL轉(zhuǎn)換 REAL
      ToInt32a."xx"::INTEGER轉(zhuǎn)換 INT
      ToInt64a."xx"::BIGINT轉(zhuǎn)換 BIGINT
      ToBooleana."xx"::BOOLEAN轉(zhuǎn)換 BOOLEAN
      ToChara."xx"::CHAR(2)轉(zhuǎn)換 CHAR

      聚合函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      MaxMAX( a."xx" )最大值
      MinMIN( a."xx" )最小值
      CountCOUNT( a."xx" )計數(shù)
      SumSUM( a."xx" )合計
      AvgAVG( a."xx" )平均

      數(shù)學(xué)函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      AbsABS( a."xx" )絕對值
      RoundROUND( a."xx" ,2 )四舍五入

      字符串函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      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")字符串拼接
      Operation”CreateTime“ >= @Now_1日期、數(shù)值、字符串范圍比較

      日期函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      AddYearsa."xx" + INTERVAL "1 YEAR"添加年份
      AddMonthsa."xx" + INTERVAL "1 MONTH"添加月份
      AddDaysa."xx" + INTERVAL "1 DAY"添加天數(shù)
      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" )獲取天數(shù)

      查詢函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      InIN ( a."xx" ,"x1","x2","x3" )In查詢
      NotInNOT IN ( a."xx" ,"x1","x2","x3" )Not In查詢

      其它函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      Equalsp.”ProductCode“ = "123"比較
      CaseCASEcase
      WhenWHENwhen
      ThenTHENthen
      ElseELSEelse
      EndENDend

      Sqlite

      類型轉(zhuǎn)換

      方法名稱解析示例值說明自定義函數(shù)
      ToStringCAST(a.[xx] AS TEXT )轉(zhuǎn)換 TEXT
      ToDateTimeDATETIME( a.[xx] )轉(zhuǎn)換 DateTime
      ToDecimalCAST(a.[xx] AS DECIMAL(10,6) )轉(zhuǎn)換 DECIMAL
      ToDoubleCAST(a.[xx] AS NUMERIC(10,6) )轉(zhuǎn)換 NUMERIC
      ToSingleCAST(a.[xx] AS FLOAT )轉(zhuǎn)換 FLOAT
      ToInt32CAST(a.[xx] AS INTEGER )轉(zhuǎn)換 INTEGER
      ToInt64CAST(a.[xx] AS BIGINT )轉(zhuǎn)換 BIGINT
      ToBooleanCAST(a.[xx] AS CHAR(1) )轉(zhuǎn)換 CHAR
      ToCharCAST(a.[xx] AS CHAR(2) )轉(zhuǎn)換 CHAR

      聚合函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      MaxMAX( a.[xx] )最大值
      MinMIN( a.[xx] )最小值
      CountCOUNT( a.[xx] )計數(shù)
      SumSUM( a.[xx] )合計
      AvgAVG( a.[xx] )平均

      數(shù)學(xué)函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      AbsABS( a.[xx] )絕對值
      RoundROUND( a.[xx] ,2 )四舍五入

      字符串函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      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" )小寫
      Operation[CreateTime] >= @Now_1日期、數(shù)值、字符串范圍比較

      日期函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      AddYearsDATETIME( a.[xx],"1 YEAR" )添加年份
      AddMonthsDATETIME( a.[xx],"1 MONTH" )添加月份
      AddDaysDATETIME( a.[xx],"1 DAY" )添加天數(shù)
      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] )獲取天數(shù)

      其它函數(shù)

      方法名稱解析示例值說明自定義函數(shù)
      Equalsp.”ProductCode“ = "123"比較
      CaseCASEcase
      WhenWHENwhen
      ThenTHENthen
      ElseELSEelse
      EndENDend

      添加自定義函數(shù)解析

      //注意:只能擴展未實現(xiàn)的方法名稱 不能覆蓋原有的實現(xiàn)                Models.DbType.MySQL.AddSqlFunc("方法名稱", (visit, method, sqlStack) =>                {                    //解析邏輯                });
      九、數(shù)據(jù)庫日志
      db.Aop.DbLog = (sql, dp) =>                {                    Console.WriteLine($"執(zhí)行Sql:{sql}");                    if (dp != null)                    {                        foreach (var item in dp)                        {                            Console.WriteLine($"參數(shù)名稱:{item.ParameterName} 參數(shù)值:{item.ParameterValue}");                        }                    }                };
      十、事務(wù)

      普通事務(wù)

      try              {                  db.Ado.BeginTran();//開啟事務(wù)                  // 執(zhí)行 CRUD                  db.Ado.CommitTran();//提交事務(wù)              }              catch (Exception ex)              {                  Console.WriteLine(ex.Message);                  db.Ado.RollbackTran();//回滾事務(wù)              }

      更大范圍的事務(wù)

      try                {                    db.BeginTran();//開啟事務(wù)                  // 執(zhí)行 CRUD                    db.CommitTran();//提交事務(wù)                }                catch (Exception ex)                {                    db.RollbackTran();//回滾事務(wù)                    Console.WriteLine(ex.Message);                }
      十一、多租戶

      改變數(shù)據(jù)庫

      //數(shù)據(jù)庫配置可從Json配置文件加載IDbContext db = new DbContext(new List() {                new DbOptions()                {                    DbId = "1",                    DbType = Models.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=0;max pool size=100;connect timeout=120;"                },                new DbOptions()                {                    DbId = "2",                    DbType = Models.DbType.MySQL,                    ProviderName = "MySqlConnector",                    FactoryName = "MySqlConnector.MySqlConnectorFactory,MySqlConnector",                    ConnectionStrings = "server=localhost;database=Test;user=root;pwd=123456789;port=3306;min pool size=0;max pool size=100;connect timeout=120;"                }});                db.ChangeDb("2");//切換到MySQL
      十二、原生特性支持
      ///     /// 產(chǎn)品    ///     [Table("ProductMain")]    public class Product    {        ///         /// 產(chǎn)品ID        ///         [Key]        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]        public int ProductId { get; set; }        ///         /// 產(chǎn)品編號        ///         [Column("ProductCode")]//不標(biāo)記默認取當(dāng)前屬性名稱        public string ProductCode { get; set; }        ///         /// 自定義1        ///         [NotMapped]        public string Custom1 { get; set; }                ///         /// 自定義2        ///         [Column(TypeName="Json")]//類型標(biāo)記為Json格式對象 匿名對象屬性以及字典值類型 IsClass&&!type.Equals(typeof(string)) 將自動序列化成Json格式        public Category Custom2 { get; set; }    }
      十三、原生Ado
      // 原始起步                // var conn = db.Ado.DbProviderFactory.CreateConnection();                // var cmd = conn.CreateCommand();                // 封裝的方法分別以Execute和Create開頭以及預(yù)處理 PrepareCommand 方法                // 該方法可以自動幫你處理執(zhí)行的預(yù)操作,主要作用是代碼復(fù)用。                // 當(dāng)有非常復(fù)雜的查詢 ORM不能滿足需求的時候可以使用原生Ado滿足業(yè)務(wù)需求                // 構(gòu)建數(shù)據(jù)集核心擴展方法 分別有 FristBuild ListBuild DictionaryBuild DictionaryListBuild                var data = db.Ado.ExecuteReader(CommandType.Text, "select * from product", null).ListBuild();
      十四、工作單元

      注冊數(shù)據(jù)庫上下文和工作單元服務(wù)

      var builder = WebApplication.CreateBuilder(args);var configuration = builder.Configuration;// 添加數(shù)據(jù)庫上下文服務(wù)builder.Services.AddFastDbContext();// 添加工作單元服務(wù)builder.Services.AddUnitOfWork();// 加載數(shù)據(jù)庫配置builder.Services.Configure>(configuration.GetSection("DbConfig"));

      實際應(yīng)用

      ///         /// 工作單元        ///         private readonly IUnitOfWork unitOfWork;        ///         /// 構(gòu)造方法        ///         /// 工作單元        public UnitOfWorkTestService(IUnitOfWork unitOfWork)        {            this.unitOfWork = unitOfWork;        }        ///         /// 測試        ///         ///         public string Test()        {            //unitOfWork 對象無需顯示使用using            var result1 = unitOfWork.Db.Insert(new Category()            {                CategoryName = "類別3"            }).Exceute();            var result2 = unitOfWork.Db.Insert(new Product()            {                ProductCode = "測試工作單元",            }).Exceute();            unitOfWork.Commit();            return "工作單元執(zhí)行完成...";        }
      十五、大數(shù)據(jù)導(dǎo)入

      批復(fù)制 僅支持SqlServer Oracle MySql PostgreSql

      var list = new List();                for (int j = 1; j <= 100000; j++)                {                    list.Add(new Product()                    {                        CategoryId = 1,                        ProductCode = $"測試編號_{Timestamp.CurrentTimestampSeconds()}_{j}",                        ProductName = $"測試名稱_{Timestamp.CurrentTimestampSeconds()}_{j}",                        CreateTime = DateTime.Now,                        Custom1 = $"測試自定義1_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom2 = $"測試自定義2_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom3 = $"測試自定義3_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom4 = $"測試自定義4_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom5 = $"測試自定義5_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom6 = $"測試自定義6_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom7 = $"測試自定義7_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom8 = $"測試自定義8_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom9 = $"測試自定義9_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom10 = $"測試自定義10_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom11 = $"測試自定義11_{Timestamp.CurrentTimestampSeconds()}_{j}",                        Custom12 = $"測試自定義12_{Timestamp.CurrentTimestampSeconds()}_{j}",                    });                }                db.Fast().BulkCopy(list);

      關(guān)鍵詞:

      相關(guān)內(nèi)容

      消費
      產(chǎn)業(yè)
      抱歉藏不住了!這些年輕車主告訴你,為何種草全新一代瑞虎7 PLUS 都說現(xiàn)在的新青年挑剔、難伺候,100分產(chǎn)品要達到200分品質(zhì),才能征服他們的心。其實對于
      【新要聞】河口吧租房信息(河口吧) 來為大家解答以上的問題。河口吧租房信息,河口吧這個很多人還不知道,
      成都大運會倒計時30天:有序推進競賽組織 具備正賽舉辦條件 世界時訊 中新社成都6月28日電記者28日從第31屆世界大學(xué)生夏季運動會(簡稱成都大
      【世界新視野】冰糖雪梨銀耳湯的做法大全_冰糖雪梨銀耳湯的做法 1、準備銀耳雪梨湯的配料,包括梨、銀耳、紅棗、枸杞、冰糖、純凈水。2
      基金
      亚洲人成网77777色在线播放| 亚洲一区二区三区四区在线观看 | 中文字幕亚洲综合久久2| 内射无码专区久久亚洲| 亚洲精品国产精品| 亚洲免费网站在线观看| 亚洲图片校园春色| 亚洲一级片在线播放| 亚洲成人免费在线观看| 亚洲国色天香视频| 亚洲一级毛片免费观看| 亚洲一区在线视频| 色天使亚洲综合在线观看| 激情亚洲一区国产精品| 亚洲av日韩av无码av| 久久精品国产亚洲av麻豆图片| 亚洲一区在线免费观看| 国产91在线|亚洲| 亚洲日韩精品无码AV海量| 亚洲狠狠色丁香婷婷综合| 亚洲AV无码专区亚洲AV桃| 成人婷婷网色偷偷亚洲男人的天堂| 亚洲午夜无码毛片av久久京东热| 亚洲人成色4444在线观看| 亚洲av无一区二区三区| 国产亚洲视频在线播放大全| 亚洲国产精品一区二区九九| 国产成人亚洲精品91专区手机| 中文亚洲AV片在线观看不卡| 亚洲国产精品无码专区影院 | 亚洲妇女无套内射精| 亚洲AV网一区二区三区| 亚洲男人在线无码视频| 国产综合精品久久亚洲| 亚洲AV无码久久精品成人| 亚洲网站在线播放| 日本亚洲免费无线码| 精品亚洲视频在线| 亚洲综合色自拍一区| 亚洲精品线在线观看| 亚洲伦理一二三四|