{"id":13458096,"url":"https://github.com/zqlovejyc/SQLBuilder","last_synced_at":"2025-03-24T14:33:08.802Z","repository":{"id":37320232,"uuid":"148109826","full_name":"zqlovejyc/SQLBuilder","owner":"zqlovejyc","description":".NET Framework4.5版本Expression表达式转换为SQL语句，支持SqlServer、MySql、Oracle、Sqlite、PostgreSql；基于Dapper实现了不同数据库对应的数据仓储Repository；","archived":false,"fork":false,"pushed_at":"2024-10-11T06:10:33.000Z","size":9416,"stargazers_count":80,"open_issues_count":0,"forks_count":22,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-07T07:06:05.058Z","etag":null,"topics":["dapper","expression","orm","repository","sql","sqlbuilder"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zqlovejyc.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-10T06:35:08.000Z","updated_at":"2024-10-11T06:10:37.000Z","dependencies_parsed_at":"2024-01-13T17:42:52.544Z","dependency_job_id":"a1001d4a-6534-4bfa-94d1-c3ea223978a7","html_url":"https://github.com/zqlovejyc/SQLBuilder","commit_stats":{"total_commits":495,"total_committers":1,"mean_commits":495.0,"dds":0.0,"last_synced_commit":"8ec6ea6b944eecf861bb721a39677a5819176b13"},"previous_names":[],"tags_count":82,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zqlovejyc%2FSQLBuilder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zqlovejyc%2FSQLBuilder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zqlovejyc%2FSQLBuilder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zqlovejyc%2FSQLBuilder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zqlovejyc","download_url":"https://codeload.github.com/zqlovejyc/SQLBuilder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245289876,"owners_count":20591148,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dapper","expression","orm","repository","sql","sqlbuilder"],"created_at":"2024-07-31T09:00:44.508Z","updated_at":"2025-03-24T14:33:08.372Z","avatar_url":"https://github.com/zqlovejyc.png","language":"C#","funding_links":[],"categories":["C\\#","C# #"],"sub_categories":[],"readme":"\u003cp\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://gitee.com/zqlovejyc/SQLBuilder.Core/raw/master/SQLBuilder.Core/Icon/sql.png\" height=\"80\"/\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![star](https://gitee.com/zqlovejyc/SQLBuilder/badge/star.svg)](https://gitee.com/zqlovejyc/SQLBuilder/stargazers) [![fork](https://gitee.com/zqlovejyc/SQLBuilder/badge/fork.svg)](https://gitee.com/zqlovejyc/SQLBuilder/members) [![GitHub stars](https://img.shields.io/github/stars/zqlovejyc/SQLBuilder?logo=github)](https://github.com/zqlovejyc/SQLBuilder/stargazers) [![GitHub forks](https://img.shields.io/github/forks/zqlovejyc/SQLBuilder?logo=github)](https://github.com/zqlovejyc/SQLBuilder/network) [![GitHub license](https://img.shields.io/badge/license-Apache2-yellow)](https://github.com/zqlovejyc/SQLBuilder/blob/master/LICENSE) [![nuget](https://img.shields.io/nuget/v/Zq.SQLBuilder.svg?cacheSeconds=10800)](https://www.nuget.org/packages//Zq.SQLBuilder)\n\n\u003c/div\u003e\n\n\u003cdiv align=\"left\"\u003e\n\n.NET Framework4.5版本Expression表达式转换为SQL语句，支持SqlServer、MySql、Oracle、Sqlite、PostgreSql；基于Dapper实现了不同数据库对应的数据仓储Repository；\n\n\u003c/div\u003e\n\n## 🌭 开源地址\n\n- Gitee：[https://gitee.com/zqlovejyc/SQLBuilder](https://gitee.com/zqlovejyc/SQLBuilder)\n- GitHub：[https://github.com/zqlovejyc/SQLBuilder](https://github.com/zqlovejyc/SQLBuilder)\n- GitLab：[https://gitlab.com/zqlovejyc/SQLBuilder](https://gitlab.com/zqlovejyc/SQLBuilder)\n- NuGet：[https://www.nuget.org/packages/Zq.SQLBuilder](https://www.nuget.org/packages/Zq.SQLBuilder)\n- MyGet：[https://www.myget.org/feed/zq-myget/package/nuget/Zq.SQLBuilder](https://www.myget.org/feed/zq-myget/package/nuget/Zq.SQLBuilder)\n\n\n## 🥥 框架扩展包\n\n| 包类型 | 名称 | 版本 | 描述 |\n| :---: | --- | :---: | --- |\n| [![nuget](https://shields.io/badge/-Nuget-blue?cacheSeconds=604800)](https://www.nuget.org/packages/Zq.SQLBuilder) | Zq.SQLBuilder | [![nuget](https://img.shields.io/nuget/v/Zq.SQLBuilder.svg?cacheSeconds=10800)](https://www.nuget.org/packages/Zq.SQLBuilder) | SQLBuilder 核心包 |\n| [![nuget](https://shields.io/badge/-Nuget-blue?cacheSeconds=604800)](https://www.nuget.org/packages/Zq.SQLBuilder.Diagnostics) | Zq.SQLBuilder.Diagnostics | [![nuget](https://img.shields.io/nuget/v/Zq.SQLBuilder.Diagnostics.svg?cacheSeconds=10800)](https://www.nuget.org/packages/Zq.SQLBuilder.Diagnostics) | SQLBuilder Diagnostics扩展包 |\n\n## 🚀 快速入门\n\n- #### ➕ 新增\n\n```csharp\n//新增\nawait _repository.InsertAsync(entity);\n\n//批量新增\nawait _repository.InsertAsync(entities);\n\n//新增\nawait SqlBuilder\n        .Insert\u003cMsdBoxEntity\u003e(() =\u003e\n            entity)\n        .ExecuteAsync(\n            _repository);\n\n//批量新增\nawait SqlBuilder\n        .Insert\u003cMsdBoxEntity\u003e(() =\u003e\n            new[]\n            {\n                new UserInfo { Name = \"张三\", Sex = 2 },\n                new UserInfo { Name = \"张三\", Sex = 2 }\n            })\n        .ExecuteAsync(\n            _repository);\n\n```\n\n- #### 🗑 删除\n\n```csharp\n//删除\nawait _repository.DeleteAsync(entity);\n\n//批量删除\nawait _repository.DeleteAsync(entitties);\n\n//条件删除\nawait _repository.DeleteAsync\u003cMsdBoxEntity\u003e(x =\u003e x.Id == \"1\");\n\n//删除\nawait SqlBuilder\n        .Delete\u003cMsdBoxEntity\u003e()\n        .Where(x =\u003e\n            x.Id == \"1\")\n        .ExecuteAsync(\n            _repository);\n\n//主键删除\nawait SqlBuilder\n        .Delete\u003cMsdBoxEntity\u003e()\n        .WithKey(\"1\")\n        .ExecuteAsync(\n            _repository);\n```\n\n- #### ✏ 更新\n\n```csharp\n//更新\nawait _repository.UpdateAsync(entity);\n\n//批量更新\nawait _repository.UpdateAsync(entities);\n\n//条件更新\nawait _repository.UpdateAsync\u003cMsdBoxEntity\u003e(x =\u003e x.Id == \"1\", () =\u003e entity);\n\n//更新\nawait SqlBuilder\n        .Update\u003cMsdBoxEntity\u003e(() =\u003e\n            entity,\n            DatabaseType.MySql,\n            isEnableFormat:true)\n        .Where(x =\u003e\n            x.Id == \"1\")\n        .ExecuteAsync(\n            _repository);\n```\n- #### 🔍 查询\n\n```csharp\n//简单查询\nawait _repository.FindListAsync\u003cMsdBoxEntity\u003e(x =\u003e x.Id == \"1\");\n\n//连接查询\nawait SqlBuilder\n        .Select\u003cUserInfo, UserInfo, Account, Student, Class, City, Country\u003e((u, t, a, s, d, e, f) =\u003e\n            new { u.Id, UId = t.Id, a.Name, StudentName = s.Name, ClassName = d.Name, e.CityName, CountryName = f.Name })\n        .Join\u003cUserInfo\u003e((x, t) =\u003e\n            x.Id == t.Id) //注意此处单表多次Join所以要指明具体表别名，否则都会读取第一个表别名\n        .Join\u003cAccount\u003e((x, y) =\u003e\n            x.Id == y.UserId)\n        .LeftJoin\u003cAccount, Student\u003e((x, y) =\u003e\n            x.Id == y.AccountId)\n        .RightJoin\u003cStudent, Class\u003e((x, y) =\u003e\n            x.Id == y.UserId)\n        .InnerJoin\u003cClass, City\u003e((x, y) =\u003e\n            x.CityId == y.Id)\n        .FullJoin\u003cCity, Country\u003e((x, y) =\u003e\n            x.CountryId == y.Id)\n        .Where(x =\u003e\n            x.Id != null)\n        .ToListAsync(\n            _repository);\n\n//分页查询\nvar condition = LinqExtensions\n                    .True\u003cUserInfo, Account\u003e()\n                    .And((x, y) =\u003e \n                        x.Id == y.UserId)\n                    .WhereIf(\n                        !name.IsNullOrEmpty(), \n                        (x, y) =\u003e name.EndsWith(\"∞\")\n                        ? x.Name.Contains(name.Trim('∞'))\n                        : x.Name == name);\nvar hasWhere = false;\nawait SqlBuilder\n        .Select\u003cUserInfo, Account\u003e(\n            (u, a) =\u003e new { u.Id, UserName = \"u.Name\" })\n        .InnerJoin\u003cAccount\u003e(\n            condition)\n        .WhereIf(\n            !name.IsNullOrEmpty(),\n            x =\u003e x.Email != null \u0026\u0026 \n            (!name.EndsWith(\"∞\") ? x.Name.Contains(name.TrimEnd('∞', '*')) : x.Name == name),\n            ref hasWhere)\n        .WhereIf(\n            !email.IsNullOrEmpty(),\n            x =\u003e x.Email == email,\n            ref hasWhere)\n        .ToPageAsync(\n            _repository.UseMasterOrSlave(false),\n            input.OrderField,\n            input.Ascending,\n            input.PageSize,\n            input.PageIndex);\n\n//仓储分页查询\nawait _repository.FindListAsync(condition, input.OrderField, input.Ascending, input.PageSize, input.PageIndex);\n\n//高级查询\nFunc\u003cstring[], string\u003e @delegate = x =\u003e $\"ks.{x[0]}{x[1]}{x[2]} WITH(NOLOCK)\";\n\nawait SqlBuilder\n        .Select\u003cUserInfo, Account, Student, Class, City, Country\u003e((u, a, s, d, e, f) =\u003e\n            new { u, a.Name, StudentName = s.Name, ClassName = d.Name, e.CityName, CountryName = f.Name },\n            tableNameFunc: @delegate)\n        .Join\u003cAccount\u003e((x, y) =\u003e\n            x.Id == y.UserId,\n            @delegate)\n        .LeftJoin\u003cAccount, Student\u003e((x, y) =\u003e\n            x.Id == y.AccountId,\n            @delegate)\n        .RightJoin\u003cClass, Student\u003e((x, y) =\u003e\n            y.Id == x.UserId,\n            @delegate)\n        .InnerJoin\u003cClass, City\u003e((x, y) =\u003e\n            x.CityId == y.Id,\n            @delegate)\n        .FullJoin\u003cCity, Country\u003e((x, y) =\u003e\n            x.CountryId == y.Id,\n            @delegate)\n        .Where(u =\u003e\n            u.Id != null)\n        .ToListAsync(\n            _repository);\n\n```\n\n- #### 🎫 队列\n\n```csharp\n//预提交队列\n_repository.AddQueue(async repo =\u003e\n    await repo.UpdateAsync\u003cUserEntity\u003e(\n        x =\u003e x.Id == \"1\",\n        () =\u003e new\n        {\n            Name = \"test\"\n        }) \u003e 0);\n\n_repository.AddQueue(async repo =\u003e\n    await repo.DeleteAsync\u003cUserEntity\u003e(x =\u003e\n        x.Enabled == 1) \u003e 0);\n\n//统一提交队列，默认开启事务\nvar res = await _repository.SaveQueueAsync();\n```\n### 🌌 IOC注入\n\n根据config配置自动注入不同类型数据仓储，支持一主多从配置\n\n```csharp\nvar builder = new ContainerBuilder();\n\n//注入SqlBuilder仓储\nbuilder.RegisterSqlBuilder(\"Base\", (sql, parameter) =\u003e\n{\n    //写入文本日志\n    if (parameter is DynamicParameters dynamicParameters)\n        _logger.LogInformation($@\"SQL语句：{sql}  参数：{dynamicParameters\n            .ParameterNames?\n            .ToDictionary(k =\u003e k, v =\u003e dynamicParameters.Get\u003cobject\u003e(v))\n            .ToJson()}\");\n    else if (parameter is OracleDynamicParameters oracleDynamicParameters)\n        _logger.LogInformation($@\"SQL语句：{sql} 参数：{oracleDynamicParameters\n            .OracleParameters\n            .ToDictionary(k =\u003e k.ParameterName, v =\u003e v.Value)\n            .ToJson()}\");\n    else\n        _logger.LogInformation($\"SQL语句：{sql}  参数：{parameter.ToJson()}\");\n\n    //返回null，不对原始sql进行任何更改，此处可以修改待执行的sql语句\n    return null;\n});\n\n//注入SqlBuilder日志诊断\nbuilder.RegisterSqlBuilderDiagnostic(\n    executeBefore: msg =\u003e Console.WriteLine(msg.Sql),\n    executeAfter: msg =\u003e Console.WriteLine(msg.ElapsedMilliseconds),\n    executeError: msg =\u003e Console.WriteLine(msg.Exception?.Message),\n    executeDispose: msg =\u003e Console.WriteLine(msg.MasterConnection.State),\n    disposeError: msg =\u003e Console.WriteLine(msg.Exception?.Message));\n\nvar container = builder.Build();\n\nvar repo = container.Resolve\u003cFunc\u003cstring, IRepository\u003e\u003e()(null);\n\nvar res = repo.Any\u003cLog\u003e(x =\u003e x.Id == 2633);\n```\n\n### ⚙ 数据库配置\n\n```csharp\n//appSettings\n\u003cadd key=\"ConnectionStrings\" value=\"{'Base':['SqlServer','Server=.;Database=TestDb;Uid=test;Pwd=123;'],'OracleDb':['Oracle','数据库连接字符串'],'MySqlDb':['MySql','数据库连接字符串'],'SqliteDb':['Sqlite','数据库连接字符串'],'PgsqlDb':['PostgreSql','数据库连接字符串']}\" /\u003e\n\n//connectionStrings\n\u003cadd name=\"ConnectionStrings\" connectionString=\"{'Base':['SqlServer','Server=.;Database=TestDb;Uid=test;Pwd=123;'],'OracleDb':['Oracle','数据库连接字符串'],'MySqlDb':['MySql','数据库连接字符串'],'SqliteDb':['Sqlite','数据库连接字符串'],'PgsqlDb':['PostgreSql','数据库连接字符串']}\"/\u003e\n```\n\n### 📰 事务\n\n```csharp\n//方式一\nIRepository trans = null;\ntry\n{\n    //开启事务\n    trans = _repository.BeginTransaction();\n\n    //数据库写操作\n    await trans.InsertAsync(entity);\n\n    //提交事务\n    trans.Commit();\n}\ncatch (Exception)\n{\n    //回滚事务\n    trans?.Rollback();\n    throw;\n}\n\n//方式二\nvar res = await _repository.ExecuteTransactionAsync(async trans =\u003e\n{\n    var retval = (await trans.InsertAsync(entity)) \u003e 0;\n\n    if (input.Action.EqualIgnoreCase(UnitAction.InDryBox))\n        code = await _unitInfoService.InDryBoxAsync(dryBoxInput);\n    else\n        code = await _unitInfoService.OutDryBoxAsync(dryBoxInput);\n\n    return code == ErrorCode.Successful \u0026\u0026 retval;\n});\n```\n### 📯 仓储+切库\n\n```csharp\nprivate readonly Func\u003cstring, IRepository\u003e _handler;\nprivate readonly IRepository _repository;\n\npublic MyService(Func\u003cstring, IRepository\u003e hander)\n{\n    _handler = hander;\n\n    //默认base数据仓储\n    _repository = hander(null);\n}\n\n//base仓储\nvar baseRepository = _handler(\"Base\");\n\n//cap仓储\nvar capRepository = _handler(\"Cap\");\n```\n\n### 🎣 读写分离\n\n```csharp\n//方式一\n_repository.Master = false;\n\n//方式二\n_repository.UseMasterOrSlave(master)\n```\n\n## 🧪 测试文档\n\n- 单元测试 [https://github.com/zqlovejyc/SQLBuilder/tree/master/SQLBuilder.UnitTest](https://github.com/zqlovejyc/SQLBuilder/tree/master/SQLBuilder.UnitTest)\n\n\n## 🍻 贡献代码\n\n`SQLBuilder` 遵循 `Apache-2.0` 开源协议，欢迎大家提交 `PR` 或 `Issue`。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzqlovejyc%2FSQLBuilder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzqlovejyc%2FSQLBuilder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzqlovejyc%2FSQLBuilder/lists"}