├── .gitignore ├── Image ├── CityTable.png ├── ClassTable.png ├── CtorTest.png ├── Engine.png ├── Normal.png ├── Relation.png ├── Runtime.png ├── Struction.png ├── StudentAndClassTable.png └── StudentTable.png ├── LICENSE ├── README.md ├── Vasily.Http ├── Configuration │ └── VasilyBuilder.cs ├── Model │ └── VasilyHttpResult.cs ├── Standard │ ├── VasilyNormalResultController.cs │ ├── VasilyRelationResultController.cs │ └── VasilyResultController.cs ├── VPController │ ├── VPCountController.cs │ ├── VPReadAndWriteController.cs │ ├── VPReadController.cs │ └── VPWriteController.cs ├── Vasily.Http.csproj ├── VasilyController.cs └── VasilyRelationController.cs ├── Vasily.sln ├── Vasily ├── SqlOperator │ ├── Collection │ │ └── SqlCollection.cs │ ├── Connector.cs │ ├── Driver │ │ └── DapperWrapper.cs │ ├── Model │ │ ├── GenericType.cs │ │ ├── IVasily.cs │ │ ├── SqlModel.cs │ │ └── SqlRelationModel.cs │ ├── Snowflake.cs │ ├── SqlLink.cs │ ├── SqlTempalte.cs │ ├── String │ │ ├── RelationSql.cs │ │ └── SqlEntity.cs │ └── VP │ │ ├── SqlCondition.cs │ │ ├── Standard │ │ └── SqlConditionBase.cs │ │ ├── Utils │ │ └── ASTParser .cs │ │ └── VasilyProtocal.cs ├── Vasily.Attributes │ ├── ColumnAttribute.cs │ ├── IgnoreAttribute.cs │ ├── NoRepeateAttribute.cs │ ├── PrimaryKeyAttribute.cs │ ├── RelationAttribute.cs │ └── TableAttribute.cs ├── Vasily.Engine │ ├── Extensions │ │ ├── EntitiesExtensions │ │ │ └── ObjectExtension.cs │ │ ├── ReflectionExtensions │ │ │ ├── IEnumerableMemberInfoExtension.cs │ │ │ ├── MemberInfoExtension.cs │ │ │ └── TypeExtension.cs │ │ └── SqlTypeExtensions │ │ │ └── DateTimeExtension.cs │ ├── SqlNormalMaker.cs │ ├── SqlRelationMaker.cs │ ├── Standard │ │ └── AbstactMaker.cs │ └── Utils │ │ ├── AttrOperator.cs │ │ ├── CtorOperator.cs │ │ ├── GsOperator.cs │ │ ├── JoinHelper.cs │ │ ├── MebOperator.cs │ │ ├── PermutationTree.cs │ │ └── SqlSpliter.cs ├── Vasily.Template │ ├── ConditionTemplate.cs │ ├── CountTemplate.cs │ ├── DeleteTemplate.cs │ ├── InsertTemplate.cs │ ├── RealtionDeleteTemplate.cs │ ├── RelationInsertTemplate.cs │ ├── RelationSelectTemplate.cs │ ├── RelationUpdateTemplate.cs │ ├── RepeateTemplate.cs │ ├── SelectTemplate.cs │ └── UpdateTemplate.cs ├── Vasily.csproj ├── Vasily.csproj.user └── VasilyRunner.cs ├── VasilyDemo ├── Demo_Connector.cs ├── Demo_RelationSql.cs ├── Demo_RelationSql_Driver.cs ├── Demo_Sql.cs ├── Demo_Sql_Driver.cs ├── Demo_Union.cs ├── Entities │ ├── City.cs │ ├── One.cs │ ├── SchoolClass.cs │ ├── Student.cs │ ├── StudentAndClass.cs │ └── Two.cs ├── Program.cs ├── VasilyDemo.csproj └── VasilyDemo.csproj.user ├── VasilyHttpDemo ├── Controllers │ ├── StudentController.cs │ └── TestVasilyController.cs ├── Entities │ ├── ShcoolClass.cs │ └── Student.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── TestEntity.cs ├── VasilyHttpDemo.csproj ├── appsettings.Development.json ├── appsettings.json └── wwwroot │ └── index.html ├── VasilyUT ├── Entity │ ├── Class.cs │ ├── Relation.cs │ ├── Student.cs │ ├── Test.cs │ └── Test2.cs ├── Program.cs ├── UnitTest_VasilyCache.cs ├── UnitTest_VasilyConditions.cs ├── UnitTest_VasilyConnectors.cs ├── UnitTest_VasilyReflectors.cs ├── UnitTest_VasilyRelation.cs ├── UnitTest_VasilyRelationEmit.cs ├── UnitTest_VasilyStaticEmit.cs ├── UnitTest_VasilySyntaxTree.cs ├── UnitTest_VasilyUnion.cs ├── UnitTest_VasilyUniqueId.cs └── VasilyUT.csproj └── _config.yml /.gitignore: -------------------------------------------------------------------------------- 1 | */bin/ 2 | */obj/ 3 | .vs/ 4 | *.user 5 | VasilyHttpDemo/Startup.cs 6 | -------------------------------------------------------------------------------- /Image/CityTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/CityTable.png -------------------------------------------------------------------------------- /Image/ClassTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/ClassTable.png -------------------------------------------------------------------------------- /Image/CtorTest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/CtorTest.png -------------------------------------------------------------------------------- /Image/Engine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/Engine.png -------------------------------------------------------------------------------- /Image/Normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/Normal.png -------------------------------------------------------------------------------- /Image/Relation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/Relation.png -------------------------------------------------------------------------------- /Image/Runtime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/Runtime.png -------------------------------------------------------------------------------- /Image/Struction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/Struction.png -------------------------------------------------------------------------------- /Image/StudentAndClassTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/StudentAndClassTable.png -------------------------------------------------------------------------------- /Image/StudentTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NMSAzulX/Vasily/28e7f9fa3ada53d40d94e2e11c792f3683b398c7/Image/StudentTable.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Hu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Vasily 2 | 3 | ------ 4 | 5 | 详情请转到![wiki](https://github.com/NMSAzulX/Vasily/wiki) 6 | 7 | #### 关系拓展 8 | 9 | * 找儿子模型 10 | 11 | ```c# 12 | [Table("relation_table")] 13 | public class TestRelation:IVasilyRelation 14 | { 15 | [PrimaryKey] 16 | public int rid{get;set;} 17 | 18 | [Relation(typeof(TestRelation))] 19 | public int parent_id{get;set;} 20 | } 21 | ``` 22 | 23 | > 看这个实体,根据我们上述的实战来看,成关系必须至少是两个实体之间,而这个类里面仅仅有一个关系注解而且还是指向自身的。 24 | > 从业务的角度上很容易看清楚这是个常见的撸自身设计,在前端很有可能是个树形展示,接下来我们使用relation扩展解析来解决这个关系操作。 25 | 26 | ```c# 27 | //新建一个类 28 | public class TestRelation_Luzishen{} 29 | //原来的类改为: 30 | [Table("relation_table")] 31 | public class TestRelation:IVasilyRelation 32 | { 33 | [PrimaryKey] 34 | [Relation(typeof(TestRelation))] 35 | public int rid{get;set;} 36 | 37 | [Relation(typeof(TestRelation_Luzishen),"rid")] 38 | public int parent_id{get;set;} 39 | } 40 | ``` 41 | 42 | 首先我们以TestRelation_为前缀创建一个类,当Vasily在解析`[Relation(typeof(TestRelation_Luzishen),"rid")]`的时候,会按照TestRelation类,rid字段生成EMIT映射操作,另外也让RelationSql<>的关系更加清晰。 43 | 44 | 当然了,也可以这样写: 45 | ```c# 46 | public class TestRelation_AnyName{ 47 | [PrimaryKey] 48 | public int rid; 49 | } 50 | 51 | [Relation(typeof(TestRelation_AnyName))] 52 | public int parent_id{get;set;} 53 | ``` 54 | 55 | ```c# 56 | var children = DapperWrapper.UseKey("sqlkey").SourceGets(father); 57 | 58 | ``` 59 | 60 | ### 语法封装以及脚本查询 61 | 62 | - #### SqlCondition 语法封装: 63 | 64 | ```c# 65 | 66 | SqlCondition c = new SqlCondition(); 67 | 68 | 69 | //普通操作符 70 | c>"id" ==> id>@id 如果采用泛型操作 id可以根据Column注解进行数据库字段的映射 71 | c!="id" ==> id<>@id 72 | 73 | 74 | //与或操作符 75 | c>"id" & (c!="id" | c<"id") ==> (id>@id AND (id!=@id OR id<@id)) 76 | 77 | 78 | //排序操作符 79 | c +"id" - "age" ==> ORDER BY id ASC, age DESC 80 | 81 | 82 | //分页操作符 83 | c ^ (2,10) ==> 分页语句,兼容MySql,SqlServer2012以后,PgSql,SqlLite 84 | 85 | 86 | //组合 87 | c>"id" ^ c -"id" ^ (current_page, size) ==> id>@id ORDER BY id DESC +分页查询 88 | 89 | 90 | //Vasily可根据语法树解析字符串脚本进而生成SQL语句,如下: 91 | "c>id ^ c-id ^(2,10)" => id>@id ORDER BY id DESC +分页查询 92 | ``` 93 | 94 | 95 | - #### VasilyProtocal(VP,瓦西里查询协议): 96 | 97 | Vasiy 提供了一个基于语法和参数化的查询协议 98 | 99 | 为了方便操作,封装了3种隐式转换: 100 | VasilyProtocal vp = script; 101 | VasilyProtocal vp = SqlCondition 102 | VasilyProtocal vp = condition=>condition..... 103 | 104 | 为了方便前端进行交互,AJAX自定义查询传送格式定位如下 105 | 106 | ```c# 107 | //可以隐式转换为vp,进而适配vasily进行查询 108 | { 109 | AcceptInstance:{ id:10000, name:"小明" }, 110 | Script:"c>id & c==name ^c - id ^(3,10)" 111 | } 112 | ``` 113 | 114 | sql 已经进行了防注入检测,参数也采用参数化处理 115 | 116 | - ### 项目计划 117 | 118 | - [x] 支持并发解析操作 119 | 120 | - [x] 使用standard兼容 121 | 122 | - [x] 支持触发式解析关系实体操作,触发生成静态关系SQL缓存 123 | 124 | - [x] 支持自动解析普通实体操作,生成静态无竞争常用SQL语句 125 | 126 | - [x] 支持唯一约束安全插入,并获取主键ID 127 | 128 | - [x] 支持手动控制主键是否参与到更新插入等操作 129 | 130 | - [x] 支持条件查询、分页查询、排序查询语法及脚本解析 131 | 132 | - [x] 支持HTTP,自动分页查询返回 133 | 134 | - [ ] 支持索引优化分页 135 | 136 | - [x] 支持语法树解析 137 | 138 | - [x] 支持前端SqlVP格式安全请求分页数据 139 | 140 | - [x] 支持数据库集合操作,包括Union,Intersect,Except,UnionAll 141 | 142 | - [x] 支持多模糊查询语法及脚本解析 143 | 144 | - [x] 支持雪花算法生成唯一ID 145 | 146 | - [x] 支持Link自定义操作 147 | 148 | - [x] 路由支持query-page-vp、query-vp路由自定义查询。 149 | 150 | - [x] 路由支持all-modify、all-add、all-delete整个实体类操作。 151 | 152 | - [x] 路由支持accurate-get、accurate-gets、accurate-page-gets、accurate-modify、accurate-add、accurate-delete、accurate-repeate路由精确操作。 153 | 154 | 155 | - [ ] 考虑未来是否只支持.NETStandard2.1 156 | 157 | - [ ] 添加常用运行时脚本解析,重构底层映射,替换dapper. 158 | 159 | 160 | 161 | - ### 注意事项 162 | 163 | - 由于dapper的API封装不够灵活,为保证性能以及减少实体类的侵入性,分页语句没有进行Ad-hoc优化,即参数化查询,因此需要手动控制计划缓存的数据库版本,还需要用户注意配置优化选项。 164 | 165 | - 由于dapper的API封装不够灵活,部分参数化操作采用DynamicParameters进行顺序添加,如关系操作的TableAPI系列。 166 | 167 | 168 | 169 | ~~~ 170 | 171 | ~~~ 172 | -------------------------------------------------------------------------------- /Vasily.Http/Configuration/VasilyBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | 4 | namespace Microsoft.Extensions.DependencyInjection 5 | { 6 | public static class VasilyBuilder 7 | { 8 | 9 | public static IServiceCollection AddVasily(this IServiceCollection service, Action action = null) 10 | { 11 | ConnectOption options = new ConnectOption(); 12 | action?.Invoke(options); 13 | VasilyRunner.Run(); 14 | return service; 15 | } 16 | 17 | //public static IServiceCollection AddVasilySqlCache(this IServiceCollection service, Action action) 18 | //{ 19 | // SqlOptions options = new SqlOptions(); 20 | // action(options); 21 | // return service; 22 | //} 23 | //public static IServiceCollection AddVasilyConnectionCache(this IServiceCollection service, Action action) 24 | //{ 25 | // ConnectionOptions options = new ConnectionOptions(); 26 | // action(options); 27 | // return service; 28 | //} 29 | } 30 | 31 | public class ConnectOption 32 | { 33 | public void Add(string key,string value) 34 | { 35 | Connector.Add(key, value); 36 | } 37 | public void Add(string key, string reader,string writter) 38 | { 39 | Connector.Add(key, reader, writter); 40 | } 41 | public void Add(string key, string reader, string writter) 42 | { 43 | Connector.Add(key, reader, writter); 44 | } 45 | public void AddRead(string key, string reader) 46 | { 47 | Connector.AddRead(key, reader); 48 | } 49 | public void AddWrite(string key, string writter) 50 | { 51 | Connector.AddWrite(key, writter); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Vasily.Http/Model/VasilyHttpResult.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.AspNetCore.Mvc 2 | { 3 | public ref struct ReturnPageResult 4 | { 5 | public string message; 6 | public object data; 7 | public int code; 8 | public int totle; 9 | public string description; 10 | } 11 | public ref struct ReturnResult 12 | { 13 | public string message; 14 | public string description; 15 | public object data; 16 | public int code; 17 | } 18 | 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /Vasily.Http/Standard/VasilyNormalResultController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System; 3 | using System.Collections.Generic; 4 | using Vasily.VP; 5 | 6 | namespace Vasily.Http.Standard 7 | { 8 | public class VasilyNormalResultController : VasilyResultController where T : class 9 | { 10 | public DapperWrapper driver; 11 | public SqlCondition c; 12 | public VasilyNormalResultController() 13 | { 14 | } 15 | public VasilyNormalResultController(string key) : this() 16 | { 17 | driver = new DapperWrapper(key); 18 | c = new SqlCondition(); 19 | } 20 | public VasilyNormalResultController(string reader, string writter) : this() 21 | { 22 | driver = new DapperWrapper(reader, writter); 23 | c = new SqlCondition(); 24 | } 25 | 26 | #region 信息返回封装,对内的 27 | /// 28 | /// 更新操作的结果返回 29 | /// 30 | /// 实例与查询条件 31 | /// 附加信息 32 | /// 33 | protected ReturnResult ModifyResult(VasilyProtocal cp, string message = "更新失败!") 34 | { 35 | return Result(driver.Modify(cp), message); 36 | } 37 | protected ReturnResult ModifyResult(T[] instances, string message = "删除失败!") 38 | { 39 | return Result(driver.ModifyByPrimary(instances), message); 40 | } 41 | /// 42 | /// 删除操作的结果返回 43 | /// 44 | /// 实例与查询条件 45 | /// 附加信息 46 | /// 47 | protected ReturnResult DeleteResult(VasilyProtocal vp, string message = "删除失败!", ForceDelete flag = ForceDelete.No) 48 | { 49 | return Result(driver.Delete(vp, flag), message); 50 | } 51 | protected ReturnResult DeleteResult(T[] instances, string message = "删除失败!") 52 | { 53 | return Result(driver.EntitiesDeleteByPrimary(instances), message); 54 | } 55 | /// 56 | /// 添加操作的结果返回 57 | /// 58 | /// 实例 59 | /// 附加信息 60 | /// 61 | protected ReturnResult AddResult(IEnumerable instances, string message = "添加失败!") 62 | { 63 | return Result(driver.Add(instances), message); 64 | } 65 | protected ReturnResult AddResult(T[] instances, string message = "添加失败!") 66 | { 67 | return Result(driver.Add(instances), message); 68 | } 69 | /// 70 | /// 安全添加操作的结果返回 71 | /// 72 | /// 实例 73 | /// 附加信息 74 | /// 75 | protected ReturnResult AddResult(T instances, string message = "添加失败!") 76 | { 77 | return Result(driver.SafeAdd(instances), message); 78 | } 79 | 80 | 81 | /// 82 | /// 用条件查询实例结果集,用条件查询总数 83 | /// 84 | /// 实例与查询条件 85 | /// 实例与查询条件 86 | /// 附加信息 87 | /// 88 | protected ReturnPageResult GetsPageResult(VasilyProtocal vp, string message = "查询失败!") 89 | { 90 | return Result(driver.Gets(vp), driver.CountWithCondition(vp), message); 91 | } 92 | /// 93 | /// 用条件查询实例结果 94 | /// 95 | /// 实例与查询条件 96 | /// 附加信息 97 | /// 98 | protected ReturnResult GetResult(VasilyProtocal vp, string message = "查询失败!") 99 | { 100 | return Result(driver.Get(vp), message); 101 | } 102 | /// 103 | /// 用条件查询实例结果集 104 | /// 105 | /// 实例与查询条件 106 | /// 附加信息 107 | /// 108 | protected ReturnResult GetsResult(VasilyProtocal vp, string message = "查询失败!") 109 | { 110 | return Result(driver.Gets(vp), message); 111 | } 112 | #endregion 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Vasily.Http/Standard/VasilyRelationResultController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using System.Collections.Generic; 3 | using Vasily.VP; 4 | 5 | namespace Vasily.Http.Standard 6 | { 7 | public class VasilyRelationResultController : VasilyResultController where T : class 8 | { 9 | public RelationWrapper driver; 10 | public SqlCondition c; 11 | public VasilyRelationResultController() 12 | { 13 | c = new SqlCondition(); 14 | } 15 | #region 信息返回封装 16 | /// 17 | /// 更新操作的结果返回 18 | /// 19 | /// 实例 20 | /// 附加信息 21 | /// 22 | protected ReturnResult ModifyResult(object value, string message = "更新失败!") 23 | { 24 | return Result(driver.SourceModify(value), message); 25 | } 26 | /// 27 | /// 后置删除操作的结果返回 28 | /// 29 | /// 实例 30 | /// 附加信息 31 | /// 32 | protected ReturnResult DeleteAftResult(object value, string message = "删除失败!") 33 | { 34 | return Result(driver.SourceAftDelete(value), message); 35 | } 36 | /// 37 | /// 前置删除操作的结果返回 38 | /// 39 | /// 实例 40 | /// 附加信息 41 | /// 42 | protected ReturnResult DeletePreResult(object value, string message = "删除失败!") 43 | { 44 | return Result(driver.SourcePreDelete(value), message); 45 | } 46 | /// 47 | /// 添加操作的结果返回 48 | /// 49 | /// 实例与查询条件 50 | /// 附加信息 51 | /// 52 | protected ReturnResult AddResult(IEnumerable instances, string message = "添加失败!") 53 | { 54 | return Result(driver.SourceAdd(instances), message); 55 | } 56 | /// 57 | /// 用条件查询实例结果集,用条件查询总数 58 | /// 59 | /// 实例 60 | /// 附加信息 61 | /// 62 | protected ReturnPageResult GetsPageResult(object value, string message = "查询失败!") 63 | { 64 | return Result(driver.SourceGets(value), driver.SourceCount(value), message); 65 | } 66 | /// 67 | /// 用条件查询实例结果 68 | /// 69 | /// 实例 70 | /// 附加信息 71 | /// 72 | protected ReturnResult GetResult(object value, string message = "查询失败!") 73 | { 74 | return Result(driver.SourceGet(value), message); 75 | } 76 | 77 | /// 78 | /// 用条件查询实例结果集 79 | /// 80 | /// 实例 81 | /// 附加信息 82 | /// 83 | protected ReturnResult GetsResult(object value, string message = "查询失败!") 84 | { 85 | return Result(driver.SourceGets(value), message); 86 | } 87 | 88 | #endregion 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Vasily.Http/Standard/VasilyResultController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Vasily.Http.Standard 4 | { 5 | 6 | public class VasilyResultController : ControllerBase 7 | { 8 | 9 | /// 10 | /// 分页 - 用布尔类型操作返回值 11 | /// 12 | /// true/false代表返回成功与否 13 | /// 总条数 14 | /// 正确提示,默认:操作成功!错误提示,默认:操作失败! 15 | /// 16 | protected ReturnPageResult BoolResult(bool value, int totle, string message = null) 17 | { 18 | ReturnPageResult _result = new ReturnPageResult(); 19 | _result.totle = totle; 20 | if (value) 21 | { 22 | _result.code = 0; 23 | _result.message = message==null?"操作成功!":message; 24 | } 25 | else 26 | { 27 | _result.code = 1; 28 | _result.message = message == null ? "操作失败!" : message; 29 | } 30 | return _result; 31 | } 32 | /// 33 | /// 分页 - 返回对象,若对象为空,则返回错误信息 34 | /// 35 | /// 需要传送的对象 36 | /// 37 | /// 正确提示,默认:操作成功!错误提示,默认:操作失败! 38 | /// 39 | protected ReturnPageResult Result(object value, int totle, string message = null) 40 | { 41 | ReturnPageResult _result = new ReturnPageResult(); 42 | _result.totle = totle; 43 | if (value != null) 44 | { 45 | _result.data = value; 46 | _result.code = 0; 47 | _result.message = message == null ? "操作成功!" : message; 48 | } 49 | else 50 | { 51 | _result.code = 1; 52 | _result.message = message == null ? "操作失败!" : message; 53 | } 54 | return _result; 55 | } 56 | /// 57 | /// 用布尔类型操作返回值 58 | /// 59 | /// true/false代表返回成功与否 60 | /// 正确提示,默认:操作成功!错误提示,默认:操作失败! 62 | protected ReturnResult BoolResult(bool value, string message = null) 63 | { 64 | ReturnResult _result = new ReturnResult(); 65 | if (value) 66 | { 67 | _result.code = 0; 68 | _result.message = message == null ? "操作成功!" : message; 69 | } 70 | else 71 | { 72 | _result.code = 1; 73 | _result.message = message == null ? "操作失败!" : message; 74 | } 75 | return _result; 76 | } 77 | /// 78 | /// 返回对象,若对象为空,则返回错误信息 79 | /// 80 | /// 需要传送的对象 81 | /// 正确提示,默认:操作成功!错误提示,默认:操作失败! 83 | protected ReturnResult Result(object value, string message = null) 84 | { 85 | ReturnResult _result = new ReturnResult(); 86 | if (value != null) 87 | { 88 | _result.data = value; 89 | _result.code = 0; 90 | _result.message = message == null ? "操作成功!" : message; 91 | } 92 | else 93 | { 94 | _result.code = 1; 95 | _result.message = message == null ? "操作失败!" : message; 96 | } 97 | return _result; 98 | } 99 | /// 100 | /// 返回提示信息 101 | /// 102 | /// 提示信息 103 | /// 状态码,默认1 104 | /// 105 | public ReturnResult Error(string value, int status = 1) 106 | { 107 | ReturnResult _result = new ReturnResult(); 108 | _result.message = value; 109 | _result.code = status; 110 | return _result; 111 | } 112 | /// 113 | /// 返回提示信息 114 | /// 115 | /// 提示信息 116 | /// 状态码,默认1 117 | /// 118 | public ReturnResult Error(int status,string value) 119 | { 120 | ReturnResult _result = new ReturnResult(); 121 | _result.message = value; 122 | _result.code = status; 123 | return _result; 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Vasily.Http/VPController/VPCountController.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.VP; 3 | 4 | namespace Microsoft.AspNetCore.Mvc 5 | { 6 | public class VPCountController : VasilyController where T : class 7 | { 8 | #region LinkQuery 9 | [HttpPost("accurate-count")] 10 | public ReturnResult VasilyLinkCount(VasilyProtocal vp) 11 | { 12 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Count(vp.Instance)); 13 | } 14 | #endregion 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Vasily.Http/VPController/VPReadAndWriteController.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.VP; 3 | 4 | namespace Microsoft.AspNetCore.Mvc 5 | { 6 | 7 | public class VPReadAndWriteController : VasilyController where T : class 8 | { 9 | public VPReadAndWriteController() 10 | { 11 | } 12 | public VPReadAndWriteController(string key) : base(key) 13 | { 14 | 15 | } 16 | public VPReadAndWriteController(string reader, string writter) : base(reader, writter) 17 | { 18 | 19 | } 20 | 21 | #region LinkQuery 22 | [HttpPost("accurate-count")] 23 | public ReturnResult VasilyLinkCount(VasilyProtocal vp) 24 | { 25 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Count(vp.Instance)); 26 | } 27 | [HttpPost("accurate-get")] 28 | public ReturnResult VasilyLinkGet(VasilyProtocal vp) 29 | { 30 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Get(vp.Instance)); 31 | } 32 | [HttpPost("accurate-gets")] 33 | public ReturnResult VasilyLinkGets(VasilyProtocal vp) 34 | { 35 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Gets(vp.Instance)); 36 | } 37 | [HttpPost("accurate-page-gets")] 38 | public ReturnPageResult VasilyLinkPageGets(VasilyProtocal vp) 39 | { 40 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Gets(vp.Instance), driver.CountWithCondition(vp)); 41 | } 42 | [HttpPost("accurate-modify")] 43 | public ReturnResult VasilyLinkModify(VasilyProtocal vp) 44 | { 45 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Modify(vp.Instance)); 46 | } 47 | [HttpPut("accurate-add")] 48 | public ReturnResult VasilyLinkAdd(VasilyProtocal vp) 49 | { 50 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Add(vp.Instance)); 51 | } 52 | [HttpDelete("accurate-delete")] 53 | public ReturnResult VasilyLinkDelete(VasilyProtocal vp) 54 | { 55 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Delete(vp.Instance)); 56 | } 57 | #endregion 58 | 59 | #region 整个实体进行操作 60 | [HttpPost("all-modify")] 61 | public ReturnResult VasilyModify(params T[] instances) 62 | { 63 | return ModifyResult(instances); 64 | } 65 | [HttpPut("all-add")] 66 | public ReturnResult VasilyAdd(params T[] instances) 67 | { 68 | return AddResult(instances); 69 | } 70 | [HttpDelete("all-delete")] 71 | public ReturnResult VasilyDelete(params T[] instances) 72 | { 73 | return DeleteResult(instances); 74 | } 75 | #endregion 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Vasily.Http/VPController/VPReadController.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.VP; 3 | 4 | namespace Microsoft.AspNetCore.Mvc 5 | { 6 | 7 | public class VPReadController : VasilyController where T : class 8 | { 9 | public VPReadController() 10 | { 11 | } 12 | public VPReadController(string key) : base(key) 13 | { 14 | 15 | } 16 | public VPReadController(string reader, string writter) : base(reader, writter) 17 | { 18 | 19 | } 20 | 21 | #region LinkQuery 22 | [HttpPost("accurate-get")] 23 | public ReturnResult VasilyLinkGet(VasilyProtocal vp) 24 | { 25 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Get(vp.Instance)); 26 | } 27 | [HttpPost("accurate-gets")] 28 | public ReturnResult VasilyLinkGets(VasilyProtocal vp) 29 | { 30 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Gets(vp.Instance)); 31 | } 32 | [HttpPost("accurate-page-gets")] 33 | public ReturnPageResult VasilyLinkPageGets(VasilyProtocal vp) 34 | { 35 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Gets(vp.Instance), driver.CountWithCondition(vp)); 36 | } 37 | #endregion 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Vasily.Http/VPController/VPWriteController.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.VP; 3 | 4 | namespace Microsoft.AspNetCore.Mvc 5 | { 6 | public class VPWriteController : VasilyController where T : class 7 | { 8 | public VPWriteController() 9 | { 10 | } 11 | public VPWriteController(string key) : base(key) 12 | { 13 | 14 | } 15 | public VPWriteController(string reader, string writter) : base(reader, writter) 16 | { 17 | 18 | } 19 | 20 | 21 | #region LinkQuery 22 | 23 | [HttpPost("accurate-modify")] 24 | public ReturnResult VasilyLinkModify(VasilyProtocal vp) 25 | { 26 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Modify(vp.Instance)); 27 | } 28 | [HttpPut("accurate-add")] 29 | public ReturnResult VasilyLinkAdd(VasilyProtocal vp) 30 | { 31 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Add(vp.Instance)); 32 | } 33 | [HttpDelete("accurate-delete")] 34 | public ReturnResult VasilyLinkDelete(VasilyProtocal vp) 35 | { 36 | return Result(SqlLink.Load(driver).Fields(vp.Fields).Conditions(vp).Delete(vp.Instance)); 37 | } 38 | #endregion 39 | 40 | #region 整个实体进行操作 41 | [HttpPost("all-modify")] 42 | public ReturnResult VasilyModify(params T[] instances) 43 | { 44 | return ModifyResult(instances); 45 | } 46 | [HttpPut("all-add")] 47 | public ReturnResult VasilyAdd(params T[] instances) 48 | { 49 | return AddResult(instances); 50 | } 51 | [HttpDelete("all-delete")] 52 | public ReturnResult VasilyDelete(params T[] instances) 53 | { 54 | return DeleteResult(instances); 55 | } 56 | #endregion 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Vasily.Http/Vasily.Http.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Vasily.Http/VasilyController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Vasily; 4 | using Vasily.Http.Standard; 5 | using Vasily.VP; 6 | 7 | namespace Microsoft.AspNetCore.Mvc 8 | { 9 | public class VasilyController : VasilyNormalResultController where T : class 10 | { 11 | public VasilyController() 12 | { 13 | } 14 | public VasilyController(string key) : base(key) 15 | { 16 | } 17 | public VasilyController(string reader, string writter) : base(reader, writter) 18 | { 19 | 20 | } 21 | #region 集合操作 22 | public void UseUnion(params string[] tables) 23 | { 24 | driver.UseCollection(SqlCollectionType.Union, tables); 25 | } 26 | public void UseExcept(params string[] tables) 27 | { 28 | driver.UseCollection(SqlCollectionType.Except, tables); 29 | } 30 | public void UseIntersect(params string[] tables) 31 | { 32 | driver.UseCollection(SqlCollectionType.Intersect, tables); 33 | } 34 | public void UseUnionAll(params string[] tables) 35 | { 36 | driver.UseCollection(SqlCollectionType.UnionAll, tables); 37 | } 38 | #endregion 39 | 40 | 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Vasily.Http/VasilyRelationController.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.Http.Standard; 3 | 4 | namespace Microsoft.AspNetCore.Mvc 5 | { 6 | 7 | public class VasilyController : VasilyRelationResultController where T : class 8 | { 9 | 10 | public VasilyController() 11 | { 12 | 13 | } 14 | 15 | public VasilyController(string key) : base() 16 | { 17 | driver = new DapperWrapper(key); 18 | 19 | } 20 | public VasilyController(string reader, string writter) : base() 21 | { 22 | driver = new DapperWrapper(reader, writter); 23 | } 24 | 25 | 26 | } 27 | public class VasilyController : VasilyRelationResultController where T : class 28 | { 29 | protected RelationWrapper SqlHandler; 30 | public VasilyController() 31 | { 32 | 33 | } 34 | 35 | public VasilyController(string key) 36 | { 37 | SqlHandler = new DapperWrapper(key); 38 | } 39 | public VasilyController(string reader, string writter) 40 | { 41 | SqlHandler = new DapperWrapper(reader, writter); 42 | } 43 | 44 | } 45 | 46 | public class VasilyController : VasilyRelationResultController where T : class 47 | { 48 | protected RelationWrapper SqlHandler; 49 | public VasilyController() 50 | { 51 | 52 | } 53 | 54 | public VasilyController(string key) 55 | { 56 | SqlHandler = new DapperWrapper(key); 57 | } 58 | public VasilyController(string reader, string writter) 59 | { 60 | SqlHandler = new DapperWrapper(reader, writter); 61 | } 62 | 63 | } 64 | public class VasilyController : VasilyRelationResultController where T : class 65 | { 66 | protected RelationWrapper SqlHandler; 67 | public VasilyController() 68 | { 69 | 70 | } 71 | 72 | public VasilyController(string key) 73 | { 74 | SqlHandler = new DapperWrapper(key); 75 | } 76 | public VasilyController(string reader, string writter) 77 | { 78 | SqlHandler = new DapperWrapper(reader, writter); 79 | } 80 | 81 | } 82 | 83 | public class VasilyController : VasilyRelationResultController where T : class 84 | { 85 | protected RelationWrapper SqlHandler; 86 | public VasilyController() 87 | { 88 | 89 | } 90 | 91 | public VasilyController(string key) 92 | { 93 | SqlHandler = new DapperWrapper(key); 94 | } 95 | public VasilyController(string reader, string writter) 96 | { 97 | SqlHandler = new DapperWrapper(reader, writter); 98 | } 99 | 100 | } 101 | public class VasilyController : VasilyRelationResultController where T : class 102 | { 103 | protected RelationWrapper SqlHandler; 104 | public VasilyController() 105 | { 106 | 107 | } 108 | 109 | public VasilyController(string key) 110 | { 111 | SqlHandler = new DapperWrapper(key); 112 | } 113 | public VasilyController(string reader, string writter) 114 | { 115 | SqlHandler = new DapperWrapper(reader, writter); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Vasily.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2041 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vasily", "Vasily\Vasily.csproj", "{E6A47583-2935-49BF-8DFE-23E865823B8D}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VasilyUT", "VasilyUT\VasilyUT.csproj", "{EE4912E8-5BD1-4AA9-8BEE-A5D5732C8B19}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VasilyDemo", "VasilyDemo\VasilyDemo.csproj", "{65608C67-3516-4C07-AF7A-C24CA271C88C}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vasily.Http", "Vasily.Http\Vasily.Http.csproj", "{1DF9F723-E697-4FC3-83EC-70AE922EDBB2}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VasilyHttpDemo", "VasilyHttpDemo\VasilyHttpDemo.csproj", "{4ACCB8C2-5631-4AA7-B83B-5224CD15C2FC}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {E6A47583-2935-49BF-8DFE-23E865823B8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {E6A47583-2935-49BF-8DFE-23E865823B8D}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {E6A47583-2935-49BF-8DFE-23E865823B8D}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {E6A47583-2935-49BF-8DFE-23E865823B8D}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {EE4912E8-5BD1-4AA9-8BEE-A5D5732C8B19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {EE4912E8-5BD1-4AA9-8BEE-A5D5732C8B19}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {EE4912E8-5BD1-4AA9-8BEE-A5D5732C8B19}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {EE4912E8-5BD1-4AA9-8BEE-A5D5732C8B19}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {65608C67-3516-4C07-AF7A-C24CA271C88C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {65608C67-3516-4C07-AF7A-C24CA271C88C}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {65608C67-3516-4C07-AF7A-C24CA271C88C}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {65608C67-3516-4C07-AF7A-C24CA271C88C}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {1DF9F723-E697-4FC3-83EC-70AE922EDBB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {1DF9F723-E697-4FC3-83EC-70AE922EDBB2}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {1DF9F723-E697-4FC3-83EC-70AE922EDBB2}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {1DF9F723-E697-4FC3-83EC-70AE922EDBB2}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {4ACCB8C2-5631-4AA7-B83B-5224CD15C2FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {4ACCB8C2-5631-4AA7-B83B-5224CD15C2FC}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {4ACCB8C2-5631-4AA7-B83B-5224CD15C2FC}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {4ACCB8C2-5631-4AA7-B83B-5224CD15C2FC}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {D3949EC7-0CFF-482E-83E6-0E3F664C4238} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/Collection/SqlCollection.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Model; 3 | 4 | namespace Vasily 5 | { 6 | public class SqlCollection 7 | { 8 | private static string Contact(string operate, params string[] sqls) 9 | { 10 | if (sqls.Length == 0) 11 | { 12 | return null; 13 | } 14 | StringBuilder result = new StringBuilder((sqls[0].Length + 2) * sqls.Length); 15 | for (int i = 0; i < sqls.Length - 1; i += 1) 16 | { 17 | result.Append('(').Append(sqls[i]).Append($") {operate} "); 18 | } 19 | result.Append('(').Append(sqls[sqls.Length-1]).Append(')'); 20 | return result.ToString(); 21 | } 22 | 23 | private static string Contact(string operate, string source_table, string source_sql, params string[] tables) 24 | { 25 | if (tables.Length == 0) 26 | { 27 | return source_sql; 28 | } 29 | StringBuilder result = new StringBuilder((source_sql.Length + 2) * tables.Length); 30 | for (int i = 0; i < tables.Length - 1; i += 1) 31 | { 32 | result.Append('(').Append(source_sql.Replace(source_table, tables[i])).Append($") {operate} "); 33 | } 34 | result.Append('(').Append(source_sql.Replace(source_table, tables[tables.Length - 1])).Append(')'); 35 | return result.ToString(); 36 | } 37 | public static string Union(params string[] sqls) 38 | { 39 | return Contact("UNION", sqls); 40 | } 41 | public static string UnionAll(params string[] sqls) 42 | { 43 | return Contact("UNION ALL", sqls); 44 | } 45 | public static string Except(params string[] sqls) 46 | { 47 | return Contact("EXCEPT", sqls); 48 | } 49 | public static string Intersect(params string[] sqls) 50 | { 51 | return Contact("INTERSECT", sqls); 52 | } 53 | 54 | public static string TableUnion(string source_table, string source_sql, params string[] tables) 55 | { 56 | return Contact("UNION", source_table, source_sql, tables); 57 | } 58 | public static string TableUnionAll(string source_table, string source_sql, params string[] tables) 59 | { 60 | return Contact("UNION ALL", source_table, source_sql, tables); 61 | } 62 | public static string TableExcept(string source_table, string source_sql, params string[] tables) 63 | { 64 | return Contact("EXCEPT", source_table, source_sql, tables); 65 | } 66 | public static string TableIntersect(string source_table, string source_sql, params string[] tables) 67 | { 68 | return Contact("INTERSECT", source_table, source_sql, tables); 69 | } 70 | public static string Collection(SqlCollectionType type, string source_table, string source_sql, params string[] tables) 71 | { 72 | switch (type) 73 | { 74 | 75 | case SqlCollectionType.Union: 76 | return TableUnion(source_table, source_sql, tables); 77 | case SqlCollectionType.UnionAll: 78 | return TableUnionAll(source_table, source_sql, tables); 79 | case SqlCollectionType.Except: 80 | return TableExcept(source_table, source_sql, tables); 81 | case SqlCollectionType.Intersect: 82 | return TableIntersect(source_table, source_sql, tables); 83 | case SqlCollectionType.None: 84 | default: 85 | return source_sql; 86 | } 87 | } 88 | public static string Collection(SqlCollectionType type, params string[] sqls) 89 | { 90 | switch (type) 91 | { 92 | case SqlCollectionType.None: 93 | case SqlCollectionType.Union: 94 | default: 95 | return Union(sqls); 96 | case SqlCollectionType.UnionAll: 97 | return UnionAll(sqls); 98 | case SqlCollectionType.Except: 99 | return Except(sqls); 100 | case SqlCollectionType.Intersect: 101 | return Intersect(sqls); 102 | } 103 | } 104 | } 105 | 106 | public class SqlCollection : SqlCollection 107 | { 108 | 109 | public static string TableUnion(string source_sql, params string[] tables) 110 | { 111 | return TableUnion(SqlModel.TableName, source_sql, tables); 112 | } 113 | public static string TableUnionAll(string source_sql, params string[] tables) 114 | { 115 | return TableUnionAll(SqlModel.TableName, source_sql, tables); 116 | } 117 | public static string TableExcept(string source_sql, params string[] tables) 118 | { 119 | return TableExcept(SqlModel.TableName, source_sql, tables); 120 | } 121 | public static string TableIntersect(string source_sql, params string[] tables) 122 | { 123 | return TableIntersect(SqlModel.TableName, source_sql, tables); 124 | } 125 | public static string Collection(SqlCollectionType type, string source_sql, params string[] tables) 126 | { 127 | switch (type) 128 | { 129 | 130 | case SqlCollectionType.Union: 131 | return TableUnion(source_sql, tables); 132 | case SqlCollectionType.UnionAll: 133 | return TableUnionAll(source_sql, tables); 134 | case SqlCollectionType.Except: 135 | return TableExcept(source_sql, tables); 136 | case SqlCollectionType.Intersect: 137 | return TableIntersect(source_sql, tables); 138 | case SqlCollectionType.None: 139 | default: 140 | return source_sql; 141 | } 142 | } 143 | } 144 | 145 | public enum SqlCollectionType 146 | { 147 | None, 148 | Union, 149 | UnionAll, 150 | Except, 151 | Intersect 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/Connector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Data; 4 | using Vasily.Engine.Utils; 5 | 6 | namespace Vasily 7 | { 8 | public delegate IDbConnection DbCreator(); 9 | 10 | //public class Connector 11 | //{ 12 | // public static ConcurrentDictionary FuncCache; 13 | // static Connector() 14 | // { 15 | // FuncCache = new ConcurrentDictionary(); 16 | // } 17 | //} 18 | 19 | public class Connector 20 | { 21 | 22 | internal static ConcurrentDictionary _info_cache; 23 | internal static ConcurrentDictionary _func_cache; 24 | 25 | private static Connector _connector; 26 | static Connector() 27 | { 28 | _info_cache = new ConcurrentDictionary(); 29 | _func_cache = new ConcurrentDictionary(); 30 | _connector = new Connector(); 31 | } 32 | 33 | /// 34 | /// 获取对应key的读取数据库的IDbConnection初始化委托 35 | /// 36 | /// 字典的key 37 | /// 初始化委托 38 | public static DbCreator ReadInitor(string key) 39 | { 40 | if (_func_cache.ContainsKey(key)) 41 | { 42 | return _func_cache[key].Read; 43 | } 44 | else 45 | { 46 | throw new NullReferenceException($"{ key }并没有添加到字典中,请检查初始化的代码!"); 47 | } 48 | } 49 | 50 | 51 | /// 52 | /// 获取对应key的写入数据库的IDbConnection初始化委托 53 | /// 54 | /// 字典的key 55 | /// 初始化委托 56 | public static DbCreator WriteInitor(string key) 57 | { 58 | if (_func_cache.ContainsKey(key)) 59 | { 60 | return _func_cache[key].Write; 61 | } 62 | else 63 | { 64 | throw new NullReferenceException($"{ key }并没有添加到字典中,请检查初始化的代码!"); 65 | } 66 | } 67 | 68 | 69 | /// 70 | /// 获取对应key的读取和写入数据库的IDbConnection初始化委托 71 | /// 72 | /// 字典的key 73 | /// 初始化读写委托元组 74 | public static (DbCreator Read, DbCreator Write) Initor(string key) 75 | { 76 | if (_func_cache.ContainsKey(key)) 77 | { 78 | return _func_cache[key]; 79 | } 80 | else 81 | { 82 | throw new NullReferenceException($"{ key }并没有添加到字典中,请检查初始化的代码!"); 83 | } 84 | } 85 | 86 | 87 | /// 88 | /// 添加一个读连接 89 | /// 90 | /// 数据库连接类型 91 | /// 字典的Key 92 | /// 读连接字符串 93 | /// 本身 94 | public static Connector AddRead(string key, string read) 95 | { 96 | //Connector.FuncCache[key] = _func_cache[key]; 97 | return AddRead(key, read, typeof(T)); 98 | } 99 | public static Connector AddRead(string key, string read, Type type) 100 | { 101 | if (!_info_cache.ContainsKey(key)) 102 | { 103 | _info_cache[key] = (Read: read, Write: null); 104 | _func_cache[key] = (Read: CtorOperator.DynamicCreateor(type, read), Write: null); 105 | } 106 | else 107 | { 108 | _info_cache[key] = (Read: read, Write: _info_cache[key].Write); 109 | _func_cache[key] = (Read: CtorOperator.DynamicCreateor(type, read), Write: _func_cache[key].Write); 110 | } 111 | 112 | return _connector; 113 | } 114 | 115 | /// 116 | /// 添加一个写连接 117 | /// 118 | /// 数据库连接类型 119 | /// 字典的Key 120 | /// 写连接字符串 121 | /// 本身 122 | public static Connector AddWrite(string key, string write) 123 | { 124 | //Connector.FuncCache[key] = _func_cache[key]; 125 | return AddWrite(key, write, typeof(T)); 126 | } 127 | public static Connector AddWrite(string key, string write, Type type) 128 | { 129 | if (!_info_cache.ContainsKey(key)) 130 | { 131 | _info_cache[key] = (Read: null, Write: write); 132 | _func_cache[key] = (Read: null, Write: CtorOperator.DynamicCreateor(type, write)); 133 | } 134 | else 135 | { 136 | _info_cache[key] = (Read: _info_cache[key].Read, Write: write); 137 | _func_cache[key] = (Read: _func_cache[key].Write, Write: CtorOperator.DynamicCreateor(type, write)); 138 | } 139 | 140 | return _connector; 141 | } 142 | 143 | /// 144 | /// 不区分读写添加初始化方案 145 | /// 146 | /// 数据库连接类型 147 | /// 字典的Key 148 | /// 连接字符串 149 | /// 150 | public static Connector Add(string key, string value) 151 | { 152 | //Connector.FuncCache[key] = _func_cache[key]; 153 | return Add(key, value, value); 154 | } 155 | 156 | /// 157 | /// 添加初始化方案 158 | /// 159 | /// 字典的key 160 | /// 读-数据库链接字符串 161 | /// 写-数据库链接字符串 162 | public static Connector Add(string key, string read, string write) 163 | { 164 | _info_cache[key] = (Read: read, Write: write); 165 | _func_cache[key] = (Read: CtorOperator.DynamicCreateor(read), Write: CtorOperator.DynamicCreateor(write)); 166 | return _connector; 167 | } 168 | 169 | /// 170 | /// 添加初始化方案 171 | /// 172 | /// 字典的key 173 | /// 读-数据库链接字符串 174 | /// 写-数据库链接字符串 175 | public static Connector Add(string key, string read, string write) 176 | { 177 | _info_cache[key] = (Read: read, Write: write); 178 | _func_cache[key] = (Read: CtorOperator.DynamicCreateor(read), Write: CtorOperator.DynamicCreateor(write)); 179 | return _connector; 180 | } 181 | } 182 | 183 | /*public ref readonly struct DbCreatorDelegate 184 | { 185 | 186 | }*/ 187 | } 188 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/Model/GenericType.cs: -------------------------------------------------------------------------------- 1 | namespace System 2 | { 3 | public class GenericType 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/Model/IVasily.cs: -------------------------------------------------------------------------------- 1 | namespace System 2 | { 3 | public interface IVasilyNormal 4 | { 5 | } 6 | 7 | public enum ForceDelete { 8 | No, 9 | Yew 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/Model/SqlRelationModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Reflection; 4 | using Vasily.Engine.Utils; 5 | 6 | namespace Vasily.Model 7 | { 8 | public class SqlRelationModel:SqlModel 9 | { 10 | public string[] Sources; 11 | public string[] Tables; 12 | 13 | public string PreTable; 14 | public string PreSource; 15 | 16 | public string AfterTable; 17 | public string AfterSource; 18 | 19 | public string[] AfterTables; 20 | public string[] AfterSources; 21 | 22 | public Type[] Types; 23 | public SqlModel EntityModel; 24 | //public SqlModel RelationModel; 25 | 26 | public Func SourceFunction; 27 | 28 | public ConcurrentDictionary TableSourceMapping; 29 | public (RelationAttribute Instance, MemberInfo Member)[] AttrMapping; 30 | 31 | 32 | 33 | public SqlRelationModel(Type type,Type[] types) 34 | { 35 | EntityType = type; 36 | _handler = new AttrOperator(type); 37 | Types = types; 38 | SourceFunction = (item) => { return SourceColumn(item); }; 39 | 40 | } 41 | 42 | public void UseDefaultFilter() 43 | { 44 | FilterFunction = (item) => 45 | { 46 | return SourceColumn(item); 47 | }; 48 | } 49 | 50 | 51 | public string SourceColumn(string item) 52 | { 53 | if (TableSourceMapping.ContainsKey(item)) 54 | { 55 | return TableSourceMapping[item]; 56 | } 57 | return item; 58 | } 59 | 60 | /// 61 | /// 设置主体类Model 62 | /// 63 | /// 64 | public void SetJoinSourceModel(SqlModel model) 65 | { 66 | EntityModel = model; 67 | } 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/Snowflake.cs: -------------------------------------------------------------------------------- 1 | using System.Threading; 2 | 3 | namespace System 4 | { 5 | public class Snowflake 6 | { 7 | //基准时间 8 | const long BaseTime = 1288834974657L; 9 | //可自定义长度 10 | const int CustomerSpacesLength = 22; 11 | 12 | static int _datacenter_length; 13 | static int _datanodes_length; 14 | static int _squence_mask; 15 | 16 | static long _info_sequence; 17 | static long _info_last_timestamp; 18 | static long _info_center_id; 19 | static long _info_node_id; 20 | 21 | readonly static object _lock = new object(); 22 | static Snowflake() 23 | { 24 | _datacenter_length = 5; 25 | _datanodes_length = 5; 26 | } 27 | /// 28 | /// 区域以及节点信息 29 | /// 30 | /// 数据中心ID 31 | /// 节点ID 32 | public static void SetNodesInfo(int center_id, int node_id) 33 | { 34 | _info_center_id = center_id; 35 | _info_node_id = node_id; 36 | } 37 | /// 38 | /// 比特位填充位设置 39 | /// 40 | /// 数据中心的比特位,默认为5位 41 | /// 数据节点的比特位,默认为5位 42 | public static void SetNodesLength(int data_center, int data_nodes) 43 | { 44 | int sequence_length = CustomerSpacesLength - data_center - data_nodes; 45 | 46 | if (data_nodes <= 0 || data_center <= 0 || sequence_length <= 0) 47 | { 48 | throw new ArgumentException("数据中心及节点位数设置有误,请检查!"); 49 | } 50 | _squence_mask = ~(-1 << sequence_length); 51 | _datacenter_length = data_center; 52 | _datanodes_length = data_nodes; 53 | } 54 | 55 | /// 56 | /// 获取唯一ID 57 | /// 58 | public static long NextId { get { return GetId(); } } 59 | public static long GetId() 60 | { 61 | lock (_lock) 62 | { 63 | long timestamp = DateTime.Now.MillisecondsStamp(); 64 | 65 | //如果上次生成时间和当前时间相同,在同一毫秒内 66 | if (_info_last_timestamp == timestamp) 67 | { 68 | //sequence自增,和sequenceMask相与一下,去掉高位 69 | _info_sequence = (_info_sequence + 1) & _squence_mask; 70 | //判断是否溢出,也就是每毫秒内超过1024,当为1024时,与sequenceMask相与,sequence就等于0 71 | if (_info_sequence == 0) 72 | { 73 | //等待到下一毫秒 74 | timestamp = TilNextMillis(); 75 | } 76 | } 77 | else 78 | { 79 | //如果和上次生成时间不同,重置sequence,就是下一毫秒开始,sequence计数重新从0开始累加, 80 | //为了保证尾数随机性更大一些,最后一位可以设置一个随机数 81 | _info_sequence = 0; 82 | } 83 | _info_last_timestamp = timestamp; 84 | return ((timestamp - BaseTime) << 22) | (_info_center_id << _datacenter_length) | (_info_node_id << _datanodes_length) | _info_sequence; 85 | } 86 | } 87 | 88 | // 防止产生的时间比之前的时间还要小(由于NTP回拨等问题). 89 | protected static long TilNextMillis() 90 | { 91 | var timestamp = DateTime.Now.MillisecondsStamp(); 92 | while (timestamp <= _info_last_timestamp) 93 | { 94 | Thread.Sleep(0); 95 | timestamp = DateTime.Now.MillisecondsStamp(); 96 | 97 | } 98 | return timestamp; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/SqlLink.cs: -------------------------------------------------------------------------------- 1 | using Dapper; 2 | using System; 3 | using System.Collections.Generic; 4 | using Vasily.Model; 5 | using Vasily.VP; 6 | 7 | namespace Vasily 8 | { 9 | public class SqlLink 10 | { 11 | private DapperWrapper _handler; 12 | private SqlModel _model; 13 | private string[] _conditions; 14 | private string _sqlCondition; 15 | 16 | /// 17 | /// 静态创建一个Link对象 18 | /// 19 | /// DapperWrapper对象 20 | /// 21 | public static SqlLink Load(DapperWrapper handler) 22 | { 23 | SqlLink instance = new SqlLink(); 24 | instance._handler = handler; 25 | instance._model = SqlModel.CopyInstance(); 26 | return instance; 27 | } 28 | 29 | /// 30 | /// 设置要操作的字段 31 | /// 32 | /// 33 | /// 34 | public SqlLink Fields(params string[] fields) 35 | { 36 | if (fields!=null) 37 | { 38 | _model.ResetMembers(fields); 39 | } 40 | return this; 41 | } 42 | 43 | 44 | /// 45 | /// 设置要操作的条件 46 | /// 47 | /// 48 | /// 49 | public SqlLink Conditions(params string[] conditions) 50 | { 51 | _conditions = conditions; 52 | return this; 53 | } 54 | public SqlLink Conditions(VasilyProtocal vp) 55 | { 56 | _sqlCondition = vp.Full; 57 | return this; 58 | } 59 | public SqlLink Conditions(Func, SqlCondition> condition) 60 | { 61 | return Conditions(condition(new SqlCondition())); ; 62 | } 63 | 64 | public SqlLink Conditions(SqlCondition condition) 65 | { 66 | _sqlCondition = condition.Full; ; 67 | return this; 68 | } 69 | 70 | /// 71 | /// 查询数据集合 72 | /// 73 | /// 74 | /// 75 | public IEnumerable Gets(object obj) 76 | { 77 | string sql = string.Empty; 78 | if (_conditions==null) 79 | { 80 | sql = SqlTemplate.CustomerSelect(_model,_sqlCondition); 81 | } 82 | else 83 | { 84 | sql = SqlTemplate.SelectWithCondition(_model,_conditions); 85 | } 86 | return _handler.Reader.Query(sql, obj); 87 | } 88 | 89 | /// 90 | /// 查询单条数据 91 | /// 92 | /// 93 | /// 94 | public S Get(object obj) 95 | { 96 | string sql = string.Empty; 97 | if (_conditions == null) 98 | { 99 | sql = SqlTemplate.CustomerSelect(_model, _sqlCondition); 100 | } 101 | else 102 | { 103 | sql = SqlTemplate.SelectWithCondition(_model, _conditions); 104 | } 105 | return _handler.Reader.QueryFirst(sql, obj); 106 | } 107 | 108 | 109 | /// 110 | /// 更新数据 111 | /// 112 | /// 113 | /// 114 | public int Modify(object obj) 115 | { 116 | string sql = string.Empty; 117 | if (_conditions == null) 118 | { 119 | sql = SqlTemplate.CustomerUpdate(_model, _sqlCondition); 120 | } 121 | else 122 | { 123 | sql = SqlTemplate.UpdateWithCondition(_model, _conditions); 124 | } 125 | return _handler.Writter.Execute(sql, obj); 126 | } 127 | 128 | 129 | /// 130 | /// 删除数据 131 | /// 132 | /// 133 | /// 134 | public int Delete(object obj) 135 | { 136 | string sql = string.Empty; 137 | if (_conditions == null) 138 | { 139 | sql = SqlTemplate.CustomerDelete(_model, _sqlCondition); 140 | } 141 | else 142 | { 143 | sql = SqlTemplate.DeleteWithCondition(_model, _conditions); 144 | } 145 | return _handler.Writter.Execute(sql, obj); 146 | } 147 | 148 | 149 | /// 150 | /// 删除数据 151 | /// 152 | /// 153 | /// 154 | public int Add(object obj) 155 | { 156 | string sql = SqlTemplate.CustomerInsert(_model); 157 | return _handler.Writter.Execute(sql, obj); 158 | } 159 | 160 | 161 | 162 | /// 163 | /// 查重数据 164 | /// 165 | /// 166 | /// 167 | public int Repeate(object obj) 168 | { 169 | string sql = SqlTemplate.RepeateCount(_model); 170 | return _handler.Reader.ExecuteScalar(sql, obj); 171 | } 172 | 173 | /// 174 | /// 查重数据 175 | /// 176 | /// 177 | /// 178 | public int Count(object obj) 179 | { 180 | string sql = string.Empty; 181 | if (_conditions == null) 182 | { 183 | sql = SqlTemplate.CustomerCount(_model, _sqlCondition); 184 | } 185 | else 186 | { 187 | sql = SqlTemplate.CountWithCondition(_model, _conditions); 188 | } 189 | return _handler.Reader.ExecuteScalar(sql, obj); 190 | } 191 | 192 | 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/SqlTempalte.cs: -------------------------------------------------------------------------------- 1 | using Vasily.Core; 2 | using Vasily.Model; 3 | 4 | namespace Vasily 5 | { 6 | public static class SqlTemplate 7 | { 8 | public static SelectTemplate Select; 9 | public static UpdateTemplate Update; 10 | public static DeleteTemplate Delete; 11 | public static InsertTemplate Insert; 12 | public static RepeateTemplate Repeate; 13 | public static CountTemplate Count; 14 | static SqlTemplate() 15 | { 16 | Select = new SelectTemplate(); 17 | Update = new UpdateTemplate(); 18 | Delete = new DeleteTemplate(); 19 | Insert = new InsertTemplate(); 20 | Repeate = new RepeateTemplate(); 21 | Count = new CountTemplate(); 22 | } 23 | 24 | 25 | /// 26 | /// 根据model信息生成 SELECT COUNT(*) FROM [TableName] WHERE + condition 27 | /// 28 | /// 29 | /// 30 | /// 31 | 32 | public static string CustomerCount(SqlModel model, string condition) 33 | { 34 | return $"{Count.SelectCount(model)} WHERE {condition}"; 35 | } 36 | 37 | /// 38 | /// 根据model信息生成 SELECT COUNT(*) FROM [TableName] WHERE [condition1]=@condition,[condition2]=@condition2..... 39 | /// 40 | /// 载有生成信息的Model 41 | /// 需要匹配的成员集合 42 | /// 查询字符串结果 43 | public static string CountWithCondition(SqlModel model, params string[] conditions) 44 | { 45 | return Count.SelectCountWithCondition(model, conditions); 46 | } 47 | 48 | 49 | 50 | /// 51 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] WHERE + condition 52 | /// 53 | /// 54 | /// 55 | /// 56 | 57 | public static string CustomerSelect(SqlModel model,string condition) 58 | { 59 | return $"{Select.Select(model)} WHERE {condition}"; 60 | } 61 | 62 | 63 | /// 64 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] WHERE [PrimaryKey] IN @keys 65 | /// 66 | /// 载有生成信息的Model 67 | /// 查询字符串结果 68 | public static string SelectIn(SqlModel model) 69 | { 70 | return Select.SelectIn(model); 71 | } 72 | 73 | 74 | /// 75 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] WHERE [condition1]=@condition,[condition2]=@condition2..... 76 | /// 77 | /// 载有生成信息的Model 78 | /// 需要匹配的成员集合 79 | /// 查询字符串结果 80 | public static string SelectWithCondition(SqlModel model, params string[] conditions) 81 | { 82 | return Select.SelectWithCondition(model,conditions); 83 | } 84 | 85 | 86 | /// 87 | /// 根据model信息生成 UPDATE [TableName] SET([member1]=@member1,[member2]...=@member2...) WHERE [condition1]=@condition,[condition2]=@condition2..... 88 | /// 89 | /// 载有生成信息的Model 90 | /// 查询字符串 91 | /// 更新字符串结果 92 | public static string CustomerUpdate(SqlModel model,string condition) 93 | { 94 | return $"{Update.Update(model)} WHERE {condition}"; 95 | } 96 | 97 | 98 | 99 | /// 100 | /// 根据model信息生成 UPDATE [TableName] SET([member1]=@member1,[member2]...=@member2...) WHERE [condition1]=@condition,[condition2]=@condition2..... 101 | /// 102 | /// 载有生成信息的Model 103 | /// 需要匹配的成员集合 104 | /// 更新字符串结果 105 | public static string UpdateWithCondition(SqlModel model, params string[] conditions) 106 | { 107 | return Update.UpdateWithCondition(model,conditions); 108 | } 109 | 110 | 111 | /// 112 | /// 生成 DELETE FROM [TableName] WHERE [condition1]=@condition1 AND [condition2]=@condition2 113 | /// 114 | /// 载有生成信息的Model 115 | /// 需要匹配的成员集合 116 | /// 删除字符串结果 117 | public static string DeleteWithCondition(SqlModel model, params string[] conditions) 118 | { 119 | return Delete.DeleteWithCondition(model,conditions); 120 | } 121 | 122 | /// 123 | /// 生成 DELETE FROM [TableName] WHERE [condition1]=@condition1 AND [condition2]=@condition2 124 | /// 125 | /// 载有生成信息的Model 126 | /// 查询字符串 127 | /// 删除字符串结果 128 | public static string CustomerDelete(SqlModel model, string condition) 129 | { 130 | return $"{Delete.Delete(model)} WHERE {condition}"; 131 | } 132 | 133 | 134 | /// 135 | /// 根据model信息生成 SELECT COUNT(*) FROM [TableName] WHERE [Member1]=@Member1 AND [Member2]=@Member2 .... 136 | /// 137 | /// 载有生成信息的Model 138 | /// 查重字符串结果 139 | public static string RepeateCount(SqlModel model) 140 | { 141 | return Repeate.RepeateCount(model); 142 | } 143 | 144 | 145 | /// 146 | /// 生成 DELETE FROM [TableName] WHERE [condition1]=@condition1 AND [condition2]=@condition2 147 | /// 148 | /// 载有生成信息的Model 149 | /// 查询字符串 150 | /// 删除字符串结果 151 | public static string CustomerInsert(SqlModel model) 152 | { 153 | return Insert.Insert(model); 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/String/RelationSql.cs: -------------------------------------------------------------------------------- 1 | using Vasily.Engine; 2 | using Vasily.Engine.Utils; 3 | 4 | namespace Vasily 5 | { 6 | 7 | public static class RelationSql 8 | { 9 | static RelationSql() 10 | { 11 | SqlRelationMaker analysis = new SqlRelationMaker(typeof(RelationSql)); 12 | } 13 | 14 | public static MemberGetter[] Getters; 15 | 16 | public static string Table; 17 | public static string Primary; 18 | 19 | 20 | 21 | public static string[] SourceConditions; 22 | public static string[] TableConditions; 23 | 24 | public static string CountFromSource; 25 | public static string GetFromSource; 26 | public static string ModifyFromSource; 27 | public static string DeletePreFromSource; 28 | public static string DeleteAftFromSource; 29 | public static string AddFromSource; 30 | 31 | public static string CountFromTable; 32 | public static string GetFromTable; 33 | public static string ModifyFromTable; 34 | public static string DeletePreFromTable; 35 | public static string DeleteAftFromTable; 36 | public static string AddFromTable; 37 | 38 | 39 | 40 | } 41 | public static class RelationSql 42 | { 43 | static RelationSql() 44 | { 45 | SqlRelationMaker analysis = new SqlRelationMaker(typeof(RelationSql)); 46 | 47 | } 48 | public static MemberGetter[] Getters; 49 | 50 | public static string Table; 51 | public static string Primary; 52 | 53 | public static string[] SourceConditions; 54 | public static string[] TableConditions; 55 | 56 | public static string CountFromSource; 57 | public static string GetFromSource; 58 | public static string ModifyFromSource; 59 | public static string DeletePreFromSource; 60 | public static string DeleteAftFromSource; 61 | public static string AddFromSource; 62 | 63 | public static string CountFromTable; 64 | public static string GetFromTable; 65 | public static string ModifyFromTable; 66 | public static string DeletePreFromTable; 67 | public static string DeleteAftFromTable; 68 | public static string AddFromTable; 69 | 70 | } 71 | public static class RelationSql 72 | { 73 | static RelationSql() 74 | { 75 | SqlRelationMaker analysis = new SqlRelationMaker(typeof(RelationSql)); 76 | } 77 | public static MemberGetter[] Getters; 78 | 79 | public static string Table; 80 | public static string Primary; 81 | 82 | public static string[] SourceConditions; 83 | public static string[] TableConditions; 84 | 85 | public static string CountFromSource; 86 | public static string GetFromSource; 87 | public static string ModifyFromSource; 88 | public static string DeletePreFromSource; 89 | public static string DeleteAftFromSource; 90 | public static string AddFromSource; 91 | 92 | public static string CountFromTable; 93 | public static string GetFromTable; 94 | public static string ModifyFromTable; 95 | public static string DeletePreFromTable; 96 | public static string DeleteAftFromTable; 97 | public static string AddFromTable; 98 | } 99 | public static class RelationSql 100 | { 101 | static RelationSql() 102 | { 103 | SqlRelationMaker analysis = new SqlRelationMaker(typeof(RelationSql)); 104 | } 105 | public static MemberGetter[] Getters; 106 | 107 | public static string Table; 108 | public static string Primary; 109 | 110 | public static string[] SourceConditions; 111 | public static string[] TableConditions; 112 | 113 | public static string CountFromSource; 114 | public static string GetFromSource; 115 | public static string ModifyFromSource; 116 | public static string DeletePreFromSource; 117 | public static string DeleteAftFromSource; 118 | public static string AddFromSource; 119 | 120 | public static string CountFromTable; 121 | public static string GetFromTable; 122 | public static string ModifyFromTable; 123 | public static string DeletePreFromTable; 124 | public static string DeleteAftFromTable; 125 | public static string AddFromTable; 126 | } 127 | public class RelationSql 128 | { 129 | static RelationSql() 130 | { 131 | SqlRelationMaker analysis = new SqlRelationMaker(typeof(RelationSql)); 132 | } 133 | public static MemberGetter[] Getters; 134 | 135 | public static string Table; 136 | public static string Primary; 137 | 138 | 139 | public static string[] SourceConditions; 140 | public static string[] TableConditions; 141 | 142 | public static string CountFromSource; 143 | public static string GetFromSource; 144 | public static string ModifyFromSource; 145 | public static string DeletePreFromSource; 146 | public static string DeleteAftFromSource; 147 | public static string AddFromSource; 148 | 149 | public static string CountFromTable; 150 | public static string GetFromTable; 151 | public static string ModifyFromTable; 152 | public static string DeletePreFromTable; 153 | public static string DeleteAftFromTable; 154 | public static string AddFromTable; 155 | } 156 | public class RelationSql 157 | { 158 | static RelationSql() 159 | { 160 | SqlRelationMaker analysis = new SqlRelationMaker(typeof(RelationSql)); 161 | 162 | } 163 | public static MemberGetter[] Getters; 164 | 165 | public static string Table; 166 | public static string Primary; 167 | 168 | public static string[] SourceConditions; 169 | public static string[] TableConditions; 170 | 171 | public static string CountFromSource; 172 | public static string GetFromSource; 173 | public static string ModifyFromSource; 174 | public static string DeletePreFromSource; 175 | public static string DeleteAftFromSource; 176 | public static string AddFromSource; 177 | 178 | public static string CountFromTable; 179 | public static string GetFromTable; 180 | public static string ModifyFromTable; 181 | public static string DeletePreFromTable; 182 | public static string DeleteAftFromTable; 183 | public static string AddFromTable; 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/String/SqlEntity.cs: -------------------------------------------------------------------------------- 1 | using Vasily.Engine.Utils; 2 | 3 | namespace Vasily 4 | { 5 | 6 | public class SqlEntity 7 | { 8 | static SqlEntity() 9 | { 10 | 11 | } 12 | 13 | 14 | public static MemberSetter SetPrimary; 15 | public static string Primary; 16 | public static string Table; 17 | 18 | public static string SelectCount; 19 | public static string SelectCountWhere; 20 | 21 | public static string SelectAll; 22 | public static string SelectAllWhere; 23 | public static string SelectAllByPrimary; 24 | public static string SelectAllIn; 25 | 26 | public static string UpdateAllWhere; 27 | public static string UpdateAllByPrimary; 28 | 29 | public static string DeleteWhere; 30 | public static string DeleteByPrimary; 31 | 32 | public static string InsertAll; 33 | 34 | public static string RepeateCount; 35 | public static string RepeateId; 36 | public static string RepeateEntities; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/VP/Standard/SqlConditionBase.cs: -------------------------------------------------------------------------------- 1 | namespace Vasily.VP.Standard 2 | { 3 | public abstract class SqlConditionBase 4 | { 5 | public virtual string Full { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/VP/Utils/ASTParser .cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | using System; 5 | using System.Collections.Generic; 6 | using Vasily.Model; 7 | 8 | namespace Vasily.VP.Utils 9 | { 10 | internal class ASTParser : CSharpSyntaxWalker 11 | { 12 | public string operator_string; 13 | public string order_string; 14 | public LinkedList> conditions; 15 | public SqlCondition order_condition; 16 | public (int, int) Page; 17 | public ASTParser() 18 | { 19 | Page.Item1 = -1; 20 | conditions = new LinkedList>(); 21 | order_condition = new SqlCondition(); 22 | order_string = null; 23 | operator_string = null; 24 | } 25 | 26 | public void OrderCondition(string name) 27 | { 28 | if (operator_string != null) 29 | { 30 | switch (operator_string) 31 | { 32 | case "+": 33 | order_condition = order_condition + name; 34 | break; 35 | case "-": 36 | order_condition = order_condition - name; 37 | break; 38 | default: 39 | break; 40 | 41 | } 42 | } 43 | } 44 | 45 | public SqlCondition Result 46 | { 47 | get 48 | { 49 | if (conditions.Last==null) 50 | { 51 | return order_condition; 52 | } 53 | if (Page.Item1 == -1) 54 | { 55 | return conditions.Last.Value ^ order_condition; 56 | } 57 | else 58 | { 59 | return conditions.Last.Value ^ order_condition ^ Page; 60 | } 61 | } 62 | } 63 | 64 | 65 | public override void VisitIdentifierName(IdentifierNameSyntax node) 66 | { 67 | string name = node.Identifier.ValueText; 68 | Console.WriteLine(name); 69 | if (name == "c") 70 | { 71 | return; 72 | } 73 | else 74 | { 75 | try 76 | { 77 | name = SqlModel.Column(name); 78 | } 79 | catch (Exception ex) 80 | { 81 | throw new Exception($"{ex.Message},另有可能是构造注入语句,请检查传入信息:{name}"); 82 | } 83 | } 84 | SqlCondition temp = new SqlCondition(); 85 | if (operator_string != null) 86 | { 87 | switch (operator_string) 88 | { 89 | case "==": 90 | conditions.AddLast(temp == name); 91 | break; 92 | case ">": 93 | conditions.AddLast(temp > name); 94 | break; 95 | case "!=": 96 | conditions.AddLast(temp != name); 97 | break; 98 | case "<": 99 | conditions.AddLast(temp < name); 100 | break; 101 | case ">=": 102 | conditions.AddLast(temp >= name); 103 | break; 104 | case "<=": 105 | conditions.AddLast(temp <= name); 106 | break; 107 | case "%": 108 | conditions.AddLast(temp % name); 109 | break; 110 | default: 111 | OrderCondition(name); 112 | break; 113 | } 114 | operator_string = null; 115 | } 116 | 117 | } 118 | 119 | public override void VisitBinaryExpression(BinaryExpressionSyntax node) 120 | { 121 | operator_string = node.OperatorToken.ValueText; 122 | Console.WriteLine(operator_string); 123 | this.Visit(node.Left); 124 | operator_string = node.OperatorToken.ValueText; 125 | this.Visit(node.Right); 126 | switch (node.OperatorToken.ValueText) 127 | { 128 | case "&": 129 | var temp2 = conditions.Last.Value; 130 | conditions.RemoveLast(); 131 | var temp1 = conditions.Last.Value; 132 | conditions.RemoveLast(); 133 | conditions.AddLast(temp1 & temp2); 134 | break; 135 | case "|": 136 | temp2 = conditions.Last.Value; 137 | conditions.RemoveLast(); 138 | temp1 = conditions.Last.Value; 139 | conditions.RemoveLast(); 140 | conditions.AddLast(temp1 | temp2); 141 | break; 142 | default: 143 | break; 144 | } 145 | } 146 | 147 | public override void VisitMethodDeclaration(MethodDeclarationSyntax node) 148 | { 149 | 150 | foreach (var item in node.Body.ChildNodes()) 151 | { 152 | Console.WriteLine(item.Kind()); 153 | this.Visit(node.Body); 154 | } 155 | } 156 | public override void VisitExpressionStatement(ExpressionStatementSyntax node) 157 | { 158 | foreach (var item in node.ChildNodes()) 159 | { 160 | Console.WriteLine(item.Kind()); 161 | this.Visit(item); 162 | } 163 | } 164 | public override void VisitTupleExpression(TupleExpressionSyntax node) 165 | { 166 | Page.Item1 = (int)(node.Arguments[0].Expression.GetFirstToken().Value); 167 | Page.Item2 = (int)(node.Arguments[1].Expression.GetFirstToken().Value); 168 | } 169 | 170 | public SqlCondition GetCondition(string value) { 171 | value = $"public void A(){{{value}}}"; 172 | SyntaxTree tree = CSharpSyntaxTree.ParseText(value); 173 | CompilationUnitSyntax root = tree.GetCompilationUnitRoot(); 174 | this.Visit(root); 175 | return Result; 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /Vasily/SqlOperator/VP/VasilyProtocal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using Vasily.VP.Standard; 5 | using Vasily.VP.Utils; 6 | 7 | namespace Vasily.VP 8 | { 9 | public class VasilyProtocal : SqlConditionBase 10 | { 11 | public static ConcurrentDictionary> Cache; 12 | static VasilyProtocal() 13 | { 14 | Cache = new ConcurrentDictionary>(); 15 | } 16 | 17 | public VasilyProtocal() 18 | { 19 | 20 | } 21 | public VasilyProtocal(string script) 22 | { 23 | Script = script; 24 | } 25 | public T AcceptInstance 26 | { 27 | set 28 | { 29 | Instance = value; 30 | } 31 | } 32 | 33 | public Dictionary AcceptDict 34 | { 35 | set 36 | { 37 | Instance = value; 38 | } 39 | } 40 | 41 | /// 42 | /// /Protocal SET Instance 43 | /// 44 | public object Instance; 45 | /// 46 | /// Protocal SET Script 47 | /// 48 | public string Script 49 | { 50 | set 51 | { 52 | if (!Cache.ContainsKey(value)) 53 | { 54 | ASTParser parser = new ASTParser(); 55 | var condition = parser.GetCondition(value); 56 | Query = condition.Query; 57 | Tails = condition.Tails; 58 | Order = condition.Order; 59 | Cache[value] = this; 60 | } 61 | else 62 | { 63 | var temp = Cache[value]; 64 | Query = temp.Query; 65 | Tails = temp.Tails; 66 | Order = temp.Order; 67 | } 68 | } 69 | } 70 | 71 | 72 | public string Query; 73 | public string Order; 74 | public string Tails; 75 | 76 | public override string Full { get { return Query + Tails; } } 77 | public string[] Fields; 78 | 79 | public override string ToString() 80 | { 81 | return Query + Tails; 82 | } 83 | public VasilyProtocal Clone() 84 | { 85 | return new VasilyProtocal() 86 | { 87 | Query = Query, 88 | Order = Order, 89 | Tails = Tails 90 | }; 91 | } 92 | 93 | //public static implicit operator VasilyProtocal(T value) 94 | //{ 95 | // return new VasilyProtocal() { Instance = value }; 96 | //} 97 | public static implicit operator VasilyProtocal(string value) 98 | { 99 | return new VasilyProtocal(value); 100 | } 101 | public static implicit operator VasilyProtocal(SqlCondition value) 102 | { 103 | var result = new VasilyProtocal(); 104 | result.Order = value.Order; 105 | result.Query = value.Query; 106 | result.Tails = value.Tails; 107 | return result; 108 | } 109 | public static implicit operator VasilyProtocal(Func, SqlCondition> func) 110 | { 111 | var result = new VasilyProtocal(); 112 | var value = func(new SqlCondition()); 113 | result.Order = value.Order; 114 | result.Query = value.Query; 115 | result.Tails = value.Tails; 116 | return result; 117 | } 118 | } 119 | 120 | public class VasilyProtocal : VasilyProtocal { 121 | public new S Instance; 122 | } 123 | 124 | } 125 | -------------------------------------------------------------------------------- /Vasily/Vasily.Attributes/ColumnAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Vasily 4 | { 5 | public class ColumnAttribute : Attribute 6 | { 7 | public string Name; 8 | 9 | public ColumnAttribute(string mapName) 10 | { 11 | Name = mapName; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Vasily/Vasily.Attributes/IgnoreAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Vasily 4 | { 5 | public class IgnoreAttribute : Attribute { } 6 | } 7 | -------------------------------------------------------------------------------- /Vasily/Vasily.Attributes/NoRepeateAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Vasily 4 | { 5 | public class NoRepeateAttribute : Attribute { } 6 | } 7 | -------------------------------------------------------------------------------- /Vasily/Vasily.Attributes/PrimaryKeyAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Vasily 4 | { 5 | public class PrimaryKeyAttribute : Attribute 6 | { 7 | public bool IsManually { get; set; } 8 | public PrimaryKeyAttribute() 9 | { 10 | 11 | } 12 | public PrimaryKeyAttribute(bool shut = false) 13 | { 14 | IsManually = shut; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Vasily/Vasily.Attributes/RelationAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily.Core; 3 | using Vasily.Engine.Utils; 4 | 5 | namespace Vasily 6 | { 7 | public class RelationAttribute : Attribute 8 | { 9 | public Type RelationType; 10 | public string ColumnName; 11 | 12 | public RelationAttribute(Type type,string column_name=null) 13 | { 14 | RelationType = type; 15 | if (column_name==null) 16 | { 17 | var info = (new AttrOperator(type)).Member(); 18 | if (info!=null) 19 | { 20 | column_name = info.Name; 21 | } 22 | else 23 | { 24 | column_name = null; 25 | } 26 | } 27 | ColumnName = column_name; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Vasily/Vasily.Attributes/TableAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Vasily 4 | { 5 | public class TableAttribute : Attribute 6 | { 7 | public static SqlType InitSqlType; 8 | static TableAttribute() 9 | { 10 | InitSqlType = SqlType.None; 11 | } 12 | 13 | public SqlType Type; 14 | public string Name; 15 | 16 | public TableAttribute(string tableName, SqlType sqlType = SqlType.None) 17 | { 18 | Name = tableName; 19 | if (sqlType == SqlType.None) 20 | { 21 | sqlType = InitSqlType; 22 | } 23 | Type = sqlType; 24 | } 25 | 26 | } 27 | 28 | public enum SqlType 29 | { 30 | MySql, 31 | MsSql, 32 | TiDb, 33 | PgSql, 34 | SqlLite, 35 | None 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Extensions/EntitiesExtensions/ObjectExtension.cs: -------------------------------------------------------------------------------- 1 | namespace Vasily.Engine.Extensions 2 | { 3 | public static class ObjectExtension 4 | { 5 | //public static VasilyProtocal Condition(this object instance, SqlCondition condition) 6 | //{ 7 | // VasilyProtocal vp = new VasilyProtocal(); 8 | // cp.Instance = instance; 9 | // cp.Query = condition.Query; 10 | // cp.Tails = condition.Tails; 11 | // cp.Order = condition.Order; 12 | // condition.Claer(); 13 | // return cp; 14 | //} 15 | //public static VasilyProtocal Condition(this object instance, string condition) 16 | //{ 17 | // var result = SqlEntity.GetCP(condition); 18 | // result.Instance = instance; 19 | // return result; 20 | //} 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Extensions/ReflectionExtensions/IEnumerableMemberInfoExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | 7 | namespace Vasily.Engine.Extensions 8 | { 9 | public static class IEnumerableMemberInfoExtension 10 | { 11 | public static string[] GetNames(this IEnumerable members) 12 | { 13 | string[] result = new string[members.Count()]; 14 | int index = 0; 15 | foreach (var item in members) 16 | { 17 | result[index] = item.Name; 18 | index += 1; 19 | } 20 | return result; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Extensions/ReflectionExtensions/MemberInfoExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace Vasily.Engine.Extensions 6 | { 7 | public static class MemberInfoExtension 8 | { 9 | public static Type GetCustomerType(this MemberInfo member) 10 | { 11 | if (member.MemberType == MemberTypes.Field) 12 | { 13 | return ((FieldInfo)member).FieldType; 14 | } 15 | else if (member.MemberType == MemberTypes.Property) 16 | { 17 | return ((PropertyInfo)member).PropertyType; 18 | } 19 | else if (member.MemberType == MemberTypes.Method) 20 | { 21 | return ((MethodInfo)member).ReturnType; 22 | } 23 | return null; 24 | } 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Extensions/ReflectionExtensions/TypeExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Vasily.Engine.Extensions 4 | { 5 | public static class TypeExtension 6 | { 7 | public static Type GetGenericType(this Type type, int index=0) 8 | { 9 | if (!type.IsGenericType) 10 | { 11 | return type; 12 | } 13 | return type.GetGenericArguments()[index]; 14 | } 15 | public static bool IsNullable(this Type type) 16 | { 17 | if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) 18 | { 19 | return true; 20 | } 21 | return false; 22 | } 23 | public static Type GetNullableType(this Type type) 24 | { 25 | return type.GetGenericType(0); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Extensions/SqlTypeExtensions/DateTimeExtension.cs: -------------------------------------------------------------------------------- 1 | namespace System 2 | { 3 | public static class DateTimeExtension 4 | { 5 | public static long MillisecondsStamp(this DateTime datetime) 6 | { 7 | return new DateTimeOffset(datetime).ToUnixTimeMilliseconds(); 8 | } 9 | public static long SecondsStamp(this DateTime datetime) 10 | { 11 | return new DateTimeOffset(datetime).ToUnixTimeSeconds(); 12 | } 13 | public static DateTime SecondsToTime(this long datetime) 14 | { 15 | DateTime dtStart = new DateTime(1970, 1, 1); 16 | return dtStart.AddSeconds(datetime); 17 | } 18 | public static DateTime MillisecondsToTime(this long datetime) 19 | { 20 | DateTime dtStart = new DateTime(1970, 1, 1); 21 | return dtStart.AddMilliseconds(datetime).ToLocalTime(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/SqlNormalMaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using Vasily.Core; 4 | using Vasily.Engine.Standard; 5 | using Vasily.Engine.Utils; 6 | using Vasily.Model; 7 | 8 | namespace Vasily.Engine 9 | { 10 | public class SqlNormalMaker : AbstactMaker 11 | { 12 | internal static ConcurrentDictionary _model_cache; 13 | 14 | public static SqlModel Create(Type type, string splite = null) 15 | { 16 | if (!_model_cache.ContainsKey(type)) 17 | { 18 | new SqlNormalMaker(type, splite); 19 | } 20 | return _model_cache[type]; 21 | } 22 | public static SqlModel Create(string splite = null) 23 | { 24 | return Create(typeof(T), splite); 25 | } 26 | 27 | 28 | static SqlNormalMaker() 29 | { 30 | _model_cache = new ConcurrentDictionary(); 31 | } 32 | 33 | public SqlNormalMaker(Type type, string splite=null) 34 | { 35 | if (type != null) 36 | { 37 | _handler = new AttrOperator(type); 38 | 39 | SqlModel model = new SqlModel(type); 40 | 41 | //分隔符解析 42 | SetSplite(model, splite); 43 | //表名解析 44 | SetTable(model); 45 | //主键解析 46 | SetPrimary(model); 47 | //忽略成员解析 48 | SetIgnores(model); 49 | //列名映射解析 50 | SetColumn(model); 51 | //生成静态泛型缓存 52 | StaticGenericModelCache(model,type); 53 | //生成静态类查询语句 54 | StaticSqlStringCache(model, type); 55 | //增加到缓存 56 | Cache(type, model); 57 | } 58 | } 59 | 60 | public override void StaticGenericModelCache(SqlModel model,Type type) 61 | { 62 | GsOperator gs = new GsOperator(typeof(SqlModel<>), type); 63 | gs.Set("PrimaryKey", model.PrimaryKey); 64 | gs.Set("TableName", model.TableName); 65 | gs.Set("Left", model.Left); 66 | gs.Set("Right", model.Right); 67 | gs.Set("Members", model.Members); 68 | gs.Set("ColumnMapping", model.ColumnMapping); 69 | gs.Set("OperatorType", model.OperatorType); 70 | } 71 | 72 | public override void StaticSqlStringCache(SqlModel model, Type type) 73 | { 74 | GsOperator gs = new GsOperator(typeof(SqlEntity<>), type); 75 | gs["SetPrimary"] = MebOperator.Setter(type, model.PrimaryKey); 76 | gs["Table"] = model.TableName; 77 | gs["Primary"] = model.PrimaryKey; 78 | 79 | CountTemplate count = new CountTemplate(); 80 | gs["SelectCount"] = count.SelectCount(model); 81 | gs["SelectCountWhere"] = count.SelectCountWhere(model); 82 | 83 | 84 | SelectTemplate select = new SelectTemplate(); 85 | gs["SelectAll"] = select.SelectAll(model); 86 | gs["SelectAllWhere"] = select.SelectAllWhere(model); 87 | gs["SelectAllByPrimary"] = select.SelectAllByPrimary(model); 88 | gs["SelectAllIn"] = select.SelectAllIn(model); 89 | 90 | 91 | UpdateTemplate update = new UpdateTemplate(); 92 | 93 | gs["UpdateAllWhere"] = update.UpdateWhere(model); 94 | gs["UpdateAllByPrimary"] = update.UpdateByPrimary(model); 95 | 96 | 97 | InsertTemplate insert = new InsertTemplate(); 98 | gs["InsertAll"] = insert.Insert(model); 99 | 100 | 101 | DeleteTemplate delete = new DeleteTemplate(); 102 | gs["DeleteWhere"] = delete.DeleteWhere(model); 103 | gs["DeleteByPrimary"] = delete.DeleteByPrimary(model); 104 | 105 | RepeateTemplate repeate = new RepeateTemplate(); 106 | var repeateModel = model.ModelWithAttr(); 107 | gs["RepeateCount"] = repeate.RepeateCount(repeateModel); 108 | gs["RepeateId"] = repeate.RepeateId(repeateModel); 109 | gs["RepeateEntities"] = repeate.RepeateEntities(repeateModel); 110 | } 111 | 112 | 113 | /// 114 | /// 将生成好的Model缓存起来 115 | /// 116 | /// 缓存的Key 117 | /// model 118 | public static void Cache(Type type, SqlModel model) 119 | { 120 | _model_cache[type] = model; 121 | } 122 | } 123 | 124 | public class SqlMaker:SqlNormalMaker { 125 | public SqlMaker() : base(typeof(T)) { } 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Standard/AbstactMaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Vasily.Engine.Extensions; 6 | using Vasily.Engine.Utils; 7 | using Vasily.Model; 8 | namespace Vasily.Engine.Standard 9 | { 10 | public class AbstactMaker where T: SqlModel 11 | { 12 | internal AttrOperator _handler; 13 | /// 14 | /// 手动设置分隔符 15 | /// 16 | /// 17 | public static void SetSplite(T model, string splite) 18 | { 19 | if (splite == null) 20 | { 21 | model.Left = default(char); 22 | model.Right = default(char); 23 | } 24 | else 25 | { 26 | model.Left = splite[0]; 27 | model.Right = splite[1]; 28 | } 29 | } 30 | 31 | /// 32 | /// 解析列映射列表 33 | /// 34 | /// 35 | public void SetColumn(T model) 36 | { 37 | ConcurrentDictionary _column_mapping = new ConcurrentDictionary(); 38 | var mappings = _handler.AttrsAndMembers(); 39 | foreach (var item in _handler._members) 40 | { 41 | _column_mapping[item.Name] = item.Name; 42 | } 43 | model.ResetMembers(_column_mapping.Values.ToArray()); 44 | foreach (var item in mappings) 45 | { 46 | _column_mapping[item.Member.Name] = item.Instance.Name; 47 | } 48 | model.ColumnMapping = _column_mapping; 49 | } 50 | 51 | 52 | /// 53 | /// 解析表注解,完善分隔符 54 | /// 55 | /// 56 | public void SetTable(T model) 57 | { 58 | var table = _handler.Instance(); 59 | if (table == null) 60 | { 61 | throw new NullReferenceException($"{_handler._type}类不存在Table注解,请检查实体类!"); 62 | } 63 | model.TableName = table.Name; 64 | model.OperatorType = table.Type; 65 | if (model.Left == default(char)) 66 | { 67 | SetSplite(model,SqlSpliter.GetSpliter(model.OperatorType)); 68 | } 69 | } 70 | 71 | // 72 | /// 解析忽略列表 73 | /// 74 | /// 75 | public void SetIgnores(T model) 76 | { 77 | 78 | var ignores = _handler.Members(); 79 | List list = new List(); 80 | foreach (var item in ignores) 81 | { 82 | list.Add(item.Name); 83 | } 84 | if (model.Members == null) 85 | { 86 | SetColumn(model); 87 | } 88 | model.RemoveMembers(list); 89 | } 90 | public SqlModel ModelWithoutAttr(T model) 91 | { 92 | var newModel = model.CopyInstance(); 93 | newModel.FilterFunction = model.FilterFunction; 94 | var attrMembers = _handler.Members(typeof(T)); 95 | newModel.RemoveMembers(attrMembers.GetNames()); 96 | return newModel; 97 | } 98 | public SqlModel ModelWithAttr(T model) 99 | { 100 | var newModel = model.CopyInstance(); 101 | newModel.FilterFunction = model.FilterFunction; 102 | var attrMembers = _handler.Members(typeof(T)); 103 | newModel.ResetMembers(attrMembers.GetNames()); 104 | return newModel; 105 | } 106 | 107 | /// 108 | /// 解析主键 109 | /// 110 | /// 111 | public void SetPrimary(T model) 112 | { 113 | var primary = _handler.AttrAndMember(); 114 | 115 | if (primary.Instance != null) 116 | { 117 | model.PrimaryKey = primary.Member.Name; 118 | model.PrimaryManually = primary.Instance.IsManually; 119 | } 120 | else 121 | { 122 | model.PrimaryKey = null; 123 | } 124 | } 125 | 126 | 127 | 128 | /// 129 | /// 构造静态泛型类缓存 130 | /// 131 | /// 132 | public virtual void StaticGenericModelCache(T model,Type type) { } 133 | 134 | /// 135 | /// 生成静态类SQL语句 136 | /// 137 | /// 138 | /// 139 | public virtual void StaticSqlStringCache(T model,Type type) 140 | { 141 | 142 | } 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Utils/AttrOperator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Reflection; 5 | 6 | namespace Vasily.Engine.Utils 7 | { 8 | public class AttrOperator 9 | { 10 | private static ConcurrentDictionary _member_cache; 11 | internal Type _type; 12 | internal MemberInfo[] _members; 13 | 14 | static AttrOperator() 15 | { 16 | _member_cache = new ConcurrentDictionary(); 17 | } 18 | public AttrOperator(Type type) 19 | { 20 | if (type==null) 21 | { 22 | return; 23 | } 24 | 25 | List cache = new List(); 26 | _type = type; 27 | if (!_member_cache.ContainsKey(type)) 28 | { 29 | _type.GetFields(); 30 | cache.AddRange(_type.GetFields()); 31 | cache.AddRange(_type.GetProperties()); 32 | _member_cache[type] = cache.ToArray(); 33 | cache.Clear(); 34 | } 35 | _members = _member_cache[type]; 36 | } 37 | 38 | 39 | /// 40 | /// 根据类型返回匹配标签的成员集合 41 | /// 42 | /// 标签类型 43 | /// 符合条件的成员集合 44 | public IEnumerable Members(Type attributeType) 45 | { 46 | List memberInfos = new List(); 47 | for (int i = 0; i < _members.Length; i += 1) 48 | { 49 | Attribute result = _members[i].GetCustomAttribute(attributeType); 50 | if (result!=null) 51 | { 52 | memberInfos.Add(_members[i]); 53 | } 54 | } 55 | return memberInfos; 56 | } 57 | public IEnumerable Members() 58 | { 59 | return Members(typeof(T)); 60 | } 61 | 62 | 63 | /// 64 | /// 根据类型返回匹配标签的第一个匹配的成员 65 | /// 66 | /// 标签类型 67 | /// 符合条件的成员 68 | public MemberInfo Member(Type attributeType) 69 | { 70 | for (int i = 0; i < _members.Length; i += 1) 71 | { 72 | Attribute result = _members[i].GetCustomAttribute(attributeType); 73 | if (result != null) 74 | { 75 | return _members[i]; 76 | } 77 | } 78 | return null; 79 | } 80 | public MemberInfo Member() 81 | { 82 | return Member(typeof(T)); 83 | } 84 | /// 85 | /// 根据标签类型返回标签实例集合.(标签在属性上唯一) 86 | /// 87 | /// 标签类型 88 | /// 实例与成员字键值对结果集 89 | public List<(T Instance, MemberInfo Member)> AttrsAndMembers() where T : Attribute 90 | { 91 | List<(T Instance, MemberInfo Member)> memberInfos = new List<(T Instance, MemberInfo Member)>(); 92 | Type findType = typeof(T); 93 | for (int i = 0; i < _members.Length; i += 1) 94 | { 95 | T result = _members[i].GetCustomAttribute(); 96 | if (result != null) 97 | { 98 | memberInfos.Add((result, _members[i])); 99 | } 100 | } 101 | return memberInfos; 102 | } 103 | 104 | 105 | /// 106 | /// 根据标签类型返回标签实例集合.(标签在属性上唯一) 107 | /// 108 | /// 标签类型 109 | /// 实例与成员键值对 110 | public (T Instance, MemberInfo Member) AttrAndMember() where T : Attribute 111 | { 112 | for (int i = 0; i < _members.Length; i += 1) 113 | { 114 | T result = _members[i].GetCustomAttribute(); 115 | 116 | if (result != null) 117 | { 118 | return (result, _members[i]); 119 | } 120 | 121 | } 122 | return (null, null); 123 | } 124 | 125 | /// 126 | /// 返回该类型上的标签实例 127 | /// 128 | /// 标签类型 129 | /// 标签实例 130 | public T Instance() where T : Attribute 131 | { 132 | T instance = _type.GetCustomAttribute(); 133 | return instance; 134 | } 135 | 136 | /// 137 | /// 返回该类型上的标签实例 138 | /// 139 | /// 标签类型 140 | /// 标签实例 141 | public IEnumerable Instances() where T : Attribute 142 | { 143 | IEnumerable instances = _type.GetCustomAttributes(); 144 | return instances; 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Utils/CtorOperator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | using System.Reflection; 4 | using System.Reflection.Emit; 5 | 6 | namespace Vasily.Engine.Utils 7 | { 8 | static class CtorOperator 9 | { 10 | /// 11 | /// 泛型类型Emit初始化动态函数 12 | /// 13 | /// 传入的数据库实例类型 14 | /// 传入的连接字符串 15 | /// 16 | internal static DbCreator DynamicCreateor(Type type,string connection) 17 | { 18 | DynamicMethod method = new DynamicMethod("Db" + Guid.NewGuid().ToString(), type, new Type[0]); 19 | ILGenerator il = method.GetILGenerator(); 20 | #if NETSTANDARD1_3 21 | ConstructorInfo ctor = info.DeclaringType.GetConstructor(null); 22 | #else 23 | ConstructorInfo ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(string) }, null); 24 | #endif 25 | il.Emit(OpCodes.Ldstr, connection); 26 | il.Emit(OpCodes.Newobj, ctor); 27 | il.Emit(OpCodes.Ret); 28 | DbCreator function = (DbCreator)(method.CreateDelegate(typeof(DbCreator))); 29 | return function; 30 | } 31 | 32 | internal static DbCreator DynamicCreateor(string connection) { 33 | return DynamicCreateor(typeof(T), connection); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Utils/GsOperator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Reflection.Emit; 5 | 6 | 7 | namespace Vasily.Engine.Utils 8 | { 9 | public delegate void StaticSetter(object value); 10 | 11 | public class GsOperator : GsOperator { 12 | public GsOperator() : base(typeof(G).GetGenericTypeDefinition(), typeof(C)) 13 | { 14 | 15 | } 16 | } 17 | 18 | public class GsOperator: GsOperator 19 | { 20 | public GsOperator(Type c_type):base(typeof(G).GetGenericTypeDefinition(), c_type) 21 | { 22 | 23 | } 24 | } 25 | /// 26 | /// 泛型类型生成器 27 | /// 28 | public class GsOperator 29 | { 30 | private Dictionary _infos; 31 | private Dictionary _dynamic_functions; 32 | 33 | 34 | /// 35 | /// 初始化函数 36 | /// 37 | /// 泛型外部类型,例如:List<> 38 | /// 泛型内部类型 39 | public GsOperator(Type g_type,params Type[] c_type) 40 | { 41 | _infos = new Dictionary(); 42 | _dynamic_functions = new Dictionary(); 43 | Type _type = g_type; 44 | if (c_type.Length!=0) 45 | { 46 | _type = g_type.MakeGenericType(c_type); 47 | } 48 | 49 | FieldInfo[] infos = _type.GetFields(BindingFlags.Static | BindingFlags.Public); 50 | 51 | for (int i = 0; i < infos.Length; i+=1) 52 | { 53 | _infos[infos[i].Name] = infos[i]; 54 | _dynamic_functions[infos[i].Name] = CreateSetter(infos[i]); 55 | } 56 | 57 | } 58 | 59 | /// 60 | /// 生成Setter方法委托,就是静态字段的emit赋值操作 61 | /// 62 | /// 字段 63 | /// 委托方法 64 | internal StaticSetter CreateSetter(FieldInfo info) 65 | { 66 | Type type = info.FieldType; 67 | DynamicMethod method = new DynamicMethod("StaticSetter" + Guid.NewGuid().ToString(), null, new Type[] { typeof(object) }); 68 | ILGenerator il = method.GetILGenerator(); 69 | il.Emit(OpCodes.Ldarg_0); 70 | if (type.IsClass && type != typeof(string) && type != typeof(object)) 71 | { 72 | il.Emit(OpCodes.Castclass, type); 73 | } 74 | else if (type.IsValueType) 75 | { 76 | il.Emit(OpCodes.Unbox_Any, type); 77 | } 78 | il.Emit(OpCodes.Stsfld, info); 79 | il.Emit(OpCodes.Ret); 80 | StaticSetter function = (StaticSetter)(method.CreateDelegate(typeof(StaticSetter))); 81 | return function; 82 | } 83 | 84 | /// 85 | /// 为静态了字段赋值提供索引操作 86 | /// 87 | /// 字段名称 88 | /// 89 | public object this[string field_name] { 90 | set 91 | { 92 | if (_dynamic_functions.ContainsKey(field_name)) 93 | { 94 | _dynamic_functions[field_name](value); 95 | } 96 | else 97 | { 98 | throw new ArgumentNullException("没有这个字段!"); 99 | } 100 | } 101 | } 102 | 103 | 104 | /// 105 | /// 为当前静态类的字段赋值 106 | /// 107 | /// 字段名称 108 | /// 值 109 | public void Set(string field_name, object value) 110 | { 111 | if (_dynamic_functions.ContainsKey(field_name)) 112 | { 113 | _dynamic_functions[field_name](value); 114 | } 115 | else 116 | { 117 | throw new ArgumentNullException("没有这个字段!"); 118 | } 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Utils/JoinHelper.cs: -------------------------------------------------------------------------------- 1 | using Vasily.Model; 2 | 3 | namespace Vasily.Engine.Utils 4 | { 5 | public class JoinHelper 6 | { 7 | public static string GetA(SqlModel model) 8 | { 9 | return $"{model.Left}V_{model.TableName}_TA{model.Right}"; 10 | } 11 | public static string GetA(SqlRelationModel model) 12 | { 13 | return $"{model.Left}V_{model.TableName}_TA{model.Right}"; 14 | } 15 | 16 | public static string GetB(SqlModel model) 17 | { 18 | return $"{model.Left}V_{model.TableName}_TB{model.Right}"; 19 | } 20 | public static string GetB(SqlRelationModel model) 21 | { 22 | return $"{model.Left}V_{model.TableName}_TB{model.Right}"; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Utils/MebOperator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Reflection.Emit; 5 | using System.Text; 6 | 7 | namespace Vasily.Engine.Utils 8 | { 9 | public delegate object MemberGetter(object value); 10 | public delegate void MemberSetter(object instance, object value); 11 | public class MebOperator 12 | { 13 | public static MemberSetter Setter(Type type, string name) 14 | { 15 | 16 | DynamicMethod method = new DynamicMethod(name + "MemberSetter", null, new Type[] { typeof(object), typeof(object) }); 17 | ILGenerator il = method.GetILGenerator(); 18 | il.Emit(OpCodes.Ldarg_0); 19 | il.Emit(OpCodes.Castclass, type); 20 | il.Emit(OpCodes.Ldarg_1); 21 | 22 | PropertyInfo property_info = type.GetProperty(name); 23 | 24 | if (property_info != null) 25 | { 26 | if (property_info.PropertyType.IsValueType) 27 | { 28 | il.Emit(OpCodes.Unbox_Any, property_info.PropertyType); 29 | } 30 | MethodInfo method_info = property_info.GetSetMethod(true); 31 | if (method_info.DeclaringType.IsValueType) 32 | { 33 | il.Emit(OpCodes.Call, method_info); 34 | } 35 | else 36 | { 37 | il.Emit(OpCodes.Callvirt, method_info); 38 | } 39 | } 40 | else 41 | { 42 | FieldInfo field_info = type.GetField(name); 43 | 44 | if (field_info != null) 45 | { 46 | if (field_info.FieldType.IsValueType) 47 | { 48 | il.Emit(OpCodes.Unbox_Any, field_info.FieldType); 49 | } 50 | il.Emit(OpCodes.Stfld, field_info); 51 | } 52 | } 53 | 54 | il.Emit(OpCodes.Ret); 55 | MemberSetter function = (MemberSetter)(method.CreateDelegate(typeof(MemberSetter))); 56 | return function; 57 | } 58 | public static MemberGetter Getter(Type type, string name) 59 | { 60 | DynamicMethod method = new DynamicMethod(name + "MemberGetter", typeof(object), new Type[] { typeof(object) }); 61 | ILGenerator il = method.GetILGenerator(); 62 | il.Emit(OpCodes.Ldarg_0); 63 | il.Emit(OpCodes.Castclass, type); 64 | 65 | Type member_type = null; 66 | PropertyInfo property_info = type.GetProperty(name); 67 | 68 | if (property_info != null) 69 | { 70 | member_type = property_info.PropertyType; 71 | MethodInfo method_info = property_info.GetGetMethod(true); 72 | if (method_info.DeclaringType.IsValueType) 73 | { 74 | il.Emit(OpCodes.Call, method_info); 75 | } 76 | else 77 | { 78 | il.Emit(OpCodes.Callvirt, method_info); 79 | } 80 | } 81 | else 82 | { 83 | FieldInfo field_info = type.GetField(name); 84 | if (field_info != null) 85 | { 86 | member_type = field_info.FieldType; 87 | il.Emit(OpCodes.Ldfld, field_info); 88 | } 89 | } 90 | 91 | if (member_type == null) 92 | { 93 | var members = type.GetMembers(); 94 | if (members.Length>5) 95 | { 96 | throw new Exception($"在{type}中没有发现{name}字段,请检查代码!"); 97 | } 98 | else 99 | { 100 | string temp_name = type.Name.Split('_')[0]; 101 | if (VasilyRunner.RelationExtentsionTyps.ContainsKey(temp_name)) 102 | { 103 | return Getter(VasilyRunner.RelationExtentsionTyps[temp_name],name); 104 | } 105 | 106 | } 107 | 108 | } 109 | else 110 | { 111 | if (member_type.IsValueType) 112 | { 113 | il.Emit(OpCodes.Box, member_type); 114 | } 115 | } 116 | il.Emit(OpCodes.Ret); 117 | MemberGetter function = (MemberGetter)(method.CreateDelegate(typeof(MemberGetter))); 118 | return function; 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Utils/PermutationTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Vasily.Engine.Utils 7 | { 8 | 9 | public class PermutationTree 10 | { 11 | public PermutationTree[] Next; 12 | public T Value; 13 | public PermutationTree(T[] elementes) 14 | { 15 | Next = new PermutationTree[elementes.Length]; 16 | for (int i = 0; i < Next.Length; i += 1) 17 | { 18 | HashSet values = new HashSet(elementes); 19 | values.Remove(elementes[i]); 20 | Next[i] = new PermutationTree(values.ToArray()); 21 | Next[i].Value = elementes[i]; 22 | } 23 | } 24 | 25 | public List> A(int deepth, PermutationTree node = null) 26 | { 27 | if (node == null) 28 | { 29 | node = this; 30 | } 31 | List> types = new List>(); 32 | if (node.Next.Length == 0 || deepth == 0) 33 | { 34 | types.Add(new List()); 35 | types[0].Add(node.Value); 36 | } 37 | else 38 | { 39 | for (int i = 0; i < node.Next.Length; i += 1) 40 | { 41 | var collection = A(deepth - 1, node.Next[i]); 42 | 43 | for (int j = 0; j < collection.Count; j += 1) 44 | { 45 | types.Add(new List()); 46 | 47 | if (node.Value != null) 48 | { 49 | types[i * collection.Count + j].Add(node.Value); 50 | } 51 | 52 | for (int z = 0; z < collection[j].Count; z += 1) 53 | { 54 | types[i * collection.Count + j].Add(collection[j][z]); 55 | } 56 | } 57 | } 58 | } 59 | return types; 60 | } 61 | 62 | public List> SumA(int minN, int maxN) 63 | { 64 | List> types = new List>(); 65 | for (int i = minN; i <= maxN; i+=1) 66 | { 67 | foreach (var item in A(i)) 68 | { 69 | types.Add(item); 70 | } 71 | } 72 | return types; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Vasily/Vasily.Engine/Utils/SqlSpliter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Vasily.Core; 5 | 6 | namespace Vasily.Engine.Utils 7 | { 8 | public class SqlSpliter 9 | { 10 | public static string GetSpliter(Type type) 11 | { 12 | AttrOperator attr = new AttrOperator(type); 13 | var _sql_type = attr.Instance().Type; 14 | string result = " "; 15 | switch (_sql_type) 16 | { 17 | case SqlType.MySql: 18 | result = "``"; 19 | break; 20 | case SqlType.MsSql: 21 | result = "[]"; 22 | break; 23 | case SqlType.TiDb: 24 | break; 25 | case SqlType.PgSql: 26 | break; 27 | case SqlType.None: 28 | break; 29 | default: 30 | break; 31 | } 32 | return result; 33 | } 34 | 35 | public static string GetSpliter(AttrOperator attr) 36 | { 37 | var _sql_type = attr.Instance().Type; 38 | string result = " "; 39 | switch (_sql_type) 40 | { 41 | case SqlType.MySql: 42 | result = "``"; 43 | break; 44 | case SqlType.MsSql: 45 | result = "[]"; 46 | break; 47 | case SqlType.TiDb: 48 | break; 49 | case SqlType.PgSql: 50 | break; 51 | case SqlType.None: 52 | break; 53 | default: 54 | break; 55 | } 56 | return result; 57 | } 58 | public static string GetSpliter(SqlType type) 59 | { 60 | string result = " "; 61 | switch (type) 62 | { 63 | case SqlType.MySql: 64 | result = "``"; 65 | break; 66 | case SqlType.MsSql: 67 | result = "[]"; 68 | break; 69 | case SqlType.TiDb: 70 | break; 71 | case SqlType.PgSql: 72 | break; 73 | case SqlType.None: 74 | break; 75 | default: 76 | break; 77 | } 78 | return result; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/ConditionTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Text; 3 | using Vasily.Model; 4 | 5 | namespace Vasily 6 | { 7 | public class ConditionTemplate 8 | { 9 | /// 10 | /// 根据model信息生成 [condition1]=@condition,[condition2]=@condition2..... 11 | /// 12 | /// 载有委托处理的Model 13 | /// 需要匹配的成员集合 14 | /// 条件字符串结果 15 | public string Condition(SqlModel model, params string[] conditions) 16 | { 17 | if (conditions==null) 18 | { 19 | return string.Empty; 20 | } 21 | StringBuilder sql = new StringBuilder(" WHERE "); 22 | for (int i = 0; i < conditions.Length; i += 1) 23 | { 24 | sql.Append(model.Left); 25 | if (model.ColFunction != null) 26 | { 27 | sql.Append(model.ColFunction(conditions[i])); 28 | } 29 | else 30 | { 31 | sql.Append(conditions[i]); 32 | } 33 | sql.Append(model.Right); 34 | 35 | sql.Append("=@"); 36 | if (model.FilterFunction != null) 37 | { 38 | sql.Append(model.FilterFunction(conditions[i])); 39 | } 40 | else 41 | { 42 | sql.Append(conditions[i]); 43 | } 44 | sql.Append(" AND "); 45 | } 46 | sql.Length -= 5; 47 | return sql.ToString(); 48 | } 49 | public string Condition(SqlModel model, IEnumerable conditions) 50 | { 51 | 52 | StringBuilder sql = new StringBuilder(" WHERE "); 53 | foreach (var item in conditions) 54 | { 55 | sql.Append(model.Left); 56 | if (model.ColFunction != null) 57 | { 58 | sql.Append(model.ColFunction(item)); 59 | } 60 | else 61 | { 62 | sql.Append(item); 63 | } 64 | sql.Append(model.Right); 65 | 66 | sql.Append("=@"); 67 | if (model.FilterFunction != null) 68 | { 69 | sql.Append(model.FilterFunction(item)); 70 | } 71 | else 72 | { 73 | sql.Append(item); 74 | } 75 | sql.Append(" AND "); 76 | } 77 | if (sql.Length>0) 78 | { 79 | sql.Length -= 5; 80 | } 81 | return sql.ToString(); 82 | } 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/CountTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Model; 3 | 4 | namespace Vasily 5 | { 6 | public class CountTemplate 7 | { 8 | /// 9 | /// 根据model信息生成 SELECT COUNT(*) FROM [TableName] 10 | /// 11 | /// 载有生成信息的Model 12 | /// 查询字符串结果 13 | public string SelectCount(SqlModel model) 14 | { 15 | StringBuilder sql = new StringBuilder(23 + model.TableName.Length); 16 | sql.Append("SELECT COUNT(*) FROM "); 17 | sql.Append(model.Left); 18 | sql.Append(model.TableName); 19 | sql.Append(model.Right); 20 | return sql.ToString(); 21 | } 22 | 23 | 24 | /// 25 | /// 根据model信息生成 SELECT COUNT(*) FROM [TableName] WHERE 26 | /// 27 | /// 载有生成信息的Model 28 | /// 查询字符串结果 29 | public string SelectCountWhere(SqlModel model) 30 | { 31 | StringBuilder sql = new StringBuilder(); 32 | sql.Append(SelectCount(model)); 33 | sql.Append(" WHERE "); 34 | return sql.ToString(); 35 | } 36 | 37 | 38 | 39 | /// 40 | /// 根据model信息生成 SELECT COUNT(*) WHERE [condition1]=@condition,[condition2]=@condition2..... 41 | /// 42 | /// 载有生成信息的Model 43 | /// 需要匹配的成员集合 44 | /// 查询字符串结果 45 | public string SelectCountWithCondition(SqlModel model, params string[] conditions) 46 | { 47 | StringBuilder sql = new StringBuilder(SelectCount(model)); 48 | ConditionTemplate template = new ConditionTemplate(); 49 | sql.Append(template.Condition(model, conditions)); 50 | return sql.ToString(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/DeleteTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Model; 3 | 4 | namespace Vasily 5 | { 6 | public class DeleteTemplate 7 | { 8 | /// 9 | /// 根据model信息生成 DELETE FROM [TableName] 10 | /// 11 | /// 载有生成信息的Model 12 | /// 删除字符串结果 13 | public string Delete(SqlModel model) 14 | { 15 | StringBuilder sql = new StringBuilder(21 + model.TableName.Length); 16 | sql.Append("DELETE FROM "); 17 | sql.Append(model.Left); 18 | sql.Append(model.TableName); 19 | sql.Append(model.Right); 20 | //sql.Append(" WHERE "); 21 | return sql.ToString(); 22 | } 23 | 24 | /// 25 | /// 根据model信息生成 DELETE FROM [TableName] WHERE 26 | /// 27 | /// 载有生成信息的Model 28 | /// 删除字符串结果 29 | public string DeleteWhere(SqlModel model) 30 | { 31 | StringBuilder sql = new StringBuilder(Delete(model)); 32 | sql.Append(" WHERE "); 33 | return sql.ToString(); 34 | } 35 | 36 | /// 37 | /// 根据model信息生成 DELETE FROM [TableName] WHERE [PrimaryKey] =@PrimaryKey 38 | /// 39 | /// 载有生成信息的Model 40 | /// 删除字符串结果 41 | public string DeleteByPrimary(SqlModel model) 42 | { 43 | if (model.PrimaryKey != null) 44 | { 45 | StringBuilder sql = new StringBuilder(23 + model.TableName.Length + model.PrimaryKey.Length * 2); 46 | sql.Append(DeleteWhere(model)); 47 | sql.Append(model.Left); 48 | sql.Append(model.PrimaryKey); 49 | sql.Append(model.Right); 50 | sql.Append("=@"); 51 | sql.Append(model.PrimaryKey); 52 | return sql.ToString(); 53 | } 54 | return null; 55 | } 56 | 57 | 58 | /// 59 | /// 生成 DELETE FROM [TableName] WHERE [condition1]=@condition1 AND [condition2]=@condition2 60 | /// 61 | /// 载有生成信息的Model 62 | /// 需要匹配的成员集合 63 | /// 删除字符串结果 64 | public string DeleteWithCondition(SqlModel model, params string[] conditions) 65 | { 66 | StringBuilder sql = new StringBuilder(Delete(model)); 67 | ConditionTemplate template = new ConditionTemplate(); 68 | sql.Append(template.Condition(model, conditions)); 69 | return sql.ToString(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/InsertTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Model; 3 | 4 | namespace Vasily 5 | { 6 | public class InsertTemplate 7 | { 8 | /// 9 | /// 根据model信息生成 INSERT INTO [TableName] ([member1],[member2]...) VALUES (@member1,@member2...) 10 | /// 11 | /// 载有生成信息的Model 12 | /// 插入字符串的结果 13 | public string Insert(SqlModel parameter_model) 14 | { 15 | var model = parameter_model; 16 | if (!parameter_model.PrimaryManually) 17 | { 18 | model = parameter_model.ModelWithoutPrimary(); 19 | model.FilterFunction = parameter_model.FilterFunction; 20 | } 21 | 22 | StringBuilder pre_str = new StringBuilder(20); 23 | StringBuilder aft_str = new StringBuilder(20); 24 | pre_str.Append(" ("); 25 | aft_str.Append('('); 26 | foreach (var item in model.Members) 27 | { 28 | pre_str.Append(model.Left); 29 | 30 | if (model.ColFunction!=null) 31 | { 32 | pre_str.Append(model.ColFunction(item)); 33 | } 34 | else 35 | { 36 | pre_str.Append(item); 37 | } 38 | 39 | pre_str.Append(model.Right); 40 | pre_str.Append(','); 41 | 42 | aft_str.Append('@'); 43 | if (model.FilterFunction != null) 44 | { 45 | aft_str.Append(model.FilterFunction(item)); 46 | } 47 | else 48 | { 49 | aft_str.Append(item); 50 | } 51 | aft_str.Append(','); 52 | } 53 | pre_str.Length -= 1; 54 | aft_str.Length -= 1; 55 | pre_str.Append(')'); 56 | aft_str.Append(')'); 57 | 58 | StringBuilder sql = new StringBuilder(40); 59 | sql.Append("INSERT INTO "); 60 | sql.Append(model.Left); 61 | sql.Append(model.TableName); 62 | sql.Append(model.Right); 63 | sql.Append(pre_str); 64 | sql.Append("VALUES"); 65 | sql.Append(aft_str); 66 | return sql.ToString(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/RealtionDeleteTemplate.cs: -------------------------------------------------------------------------------- 1 | using Vasily.Model; 2 | 3 | namespace Vasily 4 | { 5 | public class RelationDeleteTemplate 6 | { 7 | 8 | /// 9 | /// 获取删除语句 10 | /// 11 | /// 将参数化映射到标签中类的主键或其他字段上 12 | /// 13 | public string DeletePreRule(SqlRelationModel model, string pre) 14 | { 15 | DeleteTemplate delete = new DeleteTemplate(); 16 | string result = delete.DeleteWithCondition(model, pre); 17 | model.FilterFunction = null; 18 | return result; 19 | } 20 | public string DeletePreSource(SqlRelationModel model) 21 | { 22 | model.FilterFunction = (item) => { return model.SourceColumn(item); }; 23 | return DeletePreRule(model, model.PreTable); 24 | } 25 | public string DeletePreTable(SqlRelationModel model) 26 | { 27 | return DeletePreRule(model, model.PreTable); 28 | } 29 | public string DeleteAftRule(SqlRelationModel model, string[] aft) 30 | { 31 | DeleteTemplate delete = new DeleteTemplate(); 32 | return delete.DeleteWithCondition(model, aft); 33 | } 34 | public string DeleteAftSource(SqlRelationModel model) 35 | { 36 | model.FilterFunction = (item) => { return model.SourceColumn(item); }; 37 | return DeleteAftRule(model, model.AfterTables); 38 | } 39 | public string DeleteAftTable(SqlRelationModel model) 40 | { 41 | return DeleteAftRule(model, model.AfterTables); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/RelationInsertTemplate.cs: -------------------------------------------------------------------------------- 1 | using Vasily.Model; 2 | 3 | namespace Vasily 4 | { 5 | public class RelationInsertTemplate 6 | { 7 | public string InsertRule(SqlRelationModel model) 8 | { 9 | 10 | var temp_model = model.ModelWithoutPrimary(); 11 | temp_model.ResetMembers(model.Tables); 12 | 13 | InsertTemplate insert = new InsertTemplate(); 14 | string sql = insert.Insert(temp_model); 15 | model.ClearFilter(); 16 | return sql; 17 | 18 | } 19 | 20 | public string InsertSource(SqlRelationModel parameter_model) 21 | { 22 | parameter_model.UseDefaultFilter(); 23 | return InsertRule(parameter_model); 24 | } 25 | 26 | public string InsertTable(SqlRelationModel parameter_model) 27 | { 28 | return InsertRule(parameter_model); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/RelationSelectTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Engine.Utils; 3 | using Vasily.Model; 4 | 5 | namespace Vasily 6 | { 7 | public class RelationSelectTemplate 8 | { 9 | public string SelectEntitesTable(SqlRelationModel model) 10 | { 11 | SelectTemplate template = new SelectTemplate(); 12 | StringBuilder sql = new StringBuilder(); 13 | 14 | sql.Append(template.SelectAll(model.EntityModel)); 15 | sql.Append(JoinRule(model, model.Tables)); 16 | return sql.ToString(); 17 | 18 | } 19 | public string SelectEntitesSource(SqlRelationModel model) 20 | { 21 | SelectTemplate template = new SelectTemplate(); 22 | StringBuilder sql = new StringBuilder(); 23 | model.UseDefaultFilter(); 24 | sql.Append(template.SelectAll(model.EntityModel)); 25 | sql.Append(JoinRule(model, model.Sources)); 26 | model.ClearFilter(); 27 | return sql.ToString(); 28 | 29 | } 30 | public string SelectCountTable(SqlRelationModel model) 31 | { 32 | CountTemplate template = new CountTemplate(); 33 | StringBuilder sql = new StringBuilder(); 34 | 35 | sql.Append(template.SelectCount(model.EntityModel)); 36 | sql.Append(JoinRule(model, model.Tables)); 37 | return sql.ToString(); 38 | } 39 | public string SelectCountSource(SqlRelationModel model) 40 | { 41 | CountTemplate template = new CountTemplate(); 42 | StringBuilder sql = new StringBuilder(); 43 | model.UseDefaultFilter(); 44 | sql.Append(template.SelectCount(model.EntityModel)); 45 | sql.Append(JoinRule(model, model.Sources)); 46 | model.ClearFilter(); 47 | return sql.ToString(); 48 | } 49 | 50 | /// 51 | /// AS `V_SRC_TA` INNER JOIN B AS `V_SRC_TB` ON `V_SRC_TA`.ID = `V_SRC_TB`.ID..... 52 | /// 53 | /// 成员集合 54 | /// 返回条件查询SQL 55 | public string JoinRule(SqlRelationModel model,string[] conditions) 56 | { 57 | 58 | string source_table = model.EntityModel.TableName; 59 | StringBuilder sql = new StringBuilder(16 + source_table.Length); 60 | string join_inner_table = JoinHelper.GetA(model.EntityModel); 61 | string join_outter_table = JoinHelper.GetB(model); 62 | sql.Append($" AS {join_inner_table} INNER JOIN {model.Left}{model.TableName}{model.Right} AS {join_outter_table} ON "); 63 | sql.Append($"{join_inner_table}.{model.Left}{model.PreSource}{model.Right}={join_outter_table}.{model.Left}{model.ColFunction(model.Tables[0])}{model.Right}"); 64 | for (int i = 1; i < conditions.Length; i+=1) 65 | { 66 | sql.Append($" AND {join_outter_table}."); 67 | sql.Append(model.Left); 68 | if (model.ColFunction != null) 69 | { 70 | sql.Append(model.ColFunction(model.Tables[i])); 71 | } 72 | else 73 | { 74 | sql.Append(model.Tables[i]); 75 | } 76 | sql.Append(model.Right); 77 | 78 | sql.Append("=@"); 79 | if (model.FilterFunction != null) 80 | { 81 | sql.Append(model.FilterFunction(model.Tables[i])); 82 | } 83 | else 84 | { 85 | sql.Append(model.Tables[i]); 86 | } 87 | } 88 | return sql.ToString(); 89 | } 90 | 91 | 92 | } 93 | } 94 | 95 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/RelationUpdateTemplate.cs: -------------------------------------------------------------------------------- 1 | using Vasily.Model; 2 | 3 | namespace Vasily 4 | { 5 | public class RelationUpdateTemplate 6 | { 7 | public string UpdateRule(SqlRelationModel model,params string[] conditions) 8 | { 9 | UpdateTemplate template = new UpdateTemplate(); 10 | var temp_model = model.CopyInstance(); 11 | temp_model.FilterFunction = model.FilterFunction; 12 | temp_model.ResetMembers(model.PreTable); 13 | string sql = template.UpdateWithCondition(temp_model, conditions); 14 | model.ClearFilter(); 15 | return sql; 16 | } 17 | public string UpdateTable(SqlRelationModel model) 18 | { 19 | return UpdateRule(model, model.AfterTables); 20 | } 21 | public string UpdateSource(SqlRelationModel model) 22 | { 23 | model.UseDefaultFilter(); 24 | return UpdateRule(model, model.AfterTables); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/RepeateTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Model; 3 | 4 | namespace Vasily.Core 5 | { 6 | public class RepeateTemplate 7 | { 8 | 9 | 10 | 11 | /// 12 | /// 根据model信息生成 SELECT COUNT(*) FROM [TableName] WHERE [Member1]=@Member1 AND [Member2]=@Member2 .... 13 | /// 14 | /// 载有生成信息的Model 15 | /// 查重字符串结果 16 | public string RepeateCount(SqlModel model) 17 | { 18 | StringBuilder sql = new StringBuilder(40); 19 | sql.Append("SELECT COUNT(*) FROM "); 20 | sql.Append(model.Left); 21 | sql.Append(model.TableName); 22 | sql.Append(model.Right); 23 | 24 | ConditionTemplate template = new ConditionTemplate(); 25 | sql.Append(template.Condition(model, model.Members)); 26 | 27 | return sql.ToString(); 28 | } 29 | 30 | // 31 | /// 根据model信息生成 SELECT [primary] FROM [TableName] WHERE [Member1]=@Member1 AND [Member2]=@Member2 .... 32 | /// 33 | /// 载有生成信息的Model 34 | /// 查重字符串结果 35 | public string RepeateId(SqlModel model) 36 | { 37 | StringBuilder sql = new StringBuilder(40); 38 | sql.Append("SELECT "); 39 | sql.Append(model.Left); 40 | sql.Append(model.PrimaryKey); 41 | sql.Append(model.Right); 42 | sql.Append(" FROM "); 43 | sql.Append(model.Left); 44 | sql.Append(model.TableName); 45 | sql.Append(model.Right); 46 | 47 | ConditionTemplate template = new ConditionTemplate(); 48 | sql.Append(template.Condition(model, model.Members)); 49 | 50 | return sql.ToString(); 51 | } 52 | 53 | // 54 | /// 根据model信息生成 SELECT * FROM [TableName] WHERE [Member1]=@Member1 AND [Member2]=@Member2 .... 55 | /// 56 | /// 载有生成信息的Model 57 | /// 查重字符串结果 58 | public string RepeateEntities(SqlModel model) 59 | { 60 | StringBuilder sql = new StringBuilder(40); 61 | sql.Append("SELECT * FROM "); 62 | sql.Append(model.Left); 63 | sql.Append(model.TableName); 64 | sql.Append(model.Right); 65 | 66 | ConditionTemplate template = new ConditionTemplate(); 67 | sql.Append(template.Condition(model, model.Members)); 68 | 69 | return sql.ToString(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/SelectTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Model; 3 | 4 | namespace Vasily 5 | { 6 | public class SelectTemplate 7 | { 8 | /// 9 | /// 根据model信息生成 SELECT * FROM [TableName] 10 | /// 11 | /// 载有生成信息的Model 12 | /// 查询字符串结果 13 | public string SelectAll(SqlModel model) 14 | { 15 | StringBuilder sql = new StringBuilder(16 + model.TableName.Length); 16 | sql.Append("SELECT * FROM "); 17 | sql.Append(model.Left); 18 | sql.Append(model.TableName); 19 | sql.Append(model.Right); 20 | return sql.ToString(); 21 | } 22 | 23 | 24 | 25 | 26 | /// 27 | /// 根据model信息生成 SELECT * FROM [TableName] WHERE 28 | /// 29 | /// 载有生成信息的Model 30 | /// 查询字符串结果 31 | public string SelectAllWhere(SqlModel model) 32 | { 33 | StringBuilder sql = new StringBuilder(); 34 | sql.Append(SelectAll(model)); 35 | sql.Append(" WHERE "); 36 | return sql.ToString(); 37 | } 38 | 39 | 40 | 41 | 42 | 43 | 44 | /// 45 | /// 根据model信息生成 SELECT * FROM [TableName] WHERE [PrimaryKey] = @PrimaryKey 46 | /// 47 | /// 载有生成信息的Model 48 | /// 查询字符串结果 49 | public string SelectAllByPrimary(SqlModel model) 50 | { 51 | 52 | if (model.PrimaryKey != null) 53 | { 54 | StringBuilder sql = new StringBuilder(); 55 | sql.Append(SelectAllWhere(model)); 56 | sql.Append(model.Left); 57 | sql.Append(model.PrimaryKey); 58 | sql.Append(model.Right); 59 | sql.Append("=@"); 60 | sql.Append(model.PrimaryKey); 61 | return sql.ToString(); 62 | } 63 | return null; 64 | } 65 | /// 66 | /// 根据model信息生成 SELECT * FROM [TableName] WHERE [PrimaryKey] IN @keys 67 | /// 68 | /// 载有生成信息的Model 69 | /// 查询字符串结果 70 | public string SelectAllIn(SqlModel model) 71 | { 72 | StringBuilder sql = new StringBuilder(); 73 | sql.Append(SelectAllWhere(model)); 74 | sql.Append(model.Left); 75 | sql.Append(model.PrimaryKey); 76 | sql.Append(model.Right); 77 | sql.Append(" IN @keys"); 78 | return sql.ToString(); 79 | } 80 | 81 | /// 82 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] 83 | /// 84 | /// 载有生成信息的Model 85 | /// 查询字符串结果 86 | public string Select(SqlModel model) 87 | { 88 | StringBuilder sql = new StringBuilder(); 89 | sql.Append("SELECT "); 90 | foreach (var item in model.Members) 91 | { 92 | 93 | if (model.ColFunction!= null) 94 | { 95 | string sourceName = model.ColFunction(item); 96 | if (sourceName!=item) 97 | { 98 | sql.Append(model.Left); 99 | sql.Append(model.ColFunction(item)).Append(" AS "); 100 | sql.Append(model.Right); 101 | } 102 | } 103 | 104 | sql.Append(model.Left); 105 | sql.Append(item); 106 | sql.Append(model.Right); 107 | sql.Append(","); 108 | } 109 | sql.Length -= 1; 110 | sql.Append(" FROM "); 111 | sql.Append(model.Left); 112 | sql.Append(model.TableName); 113 | sql.Append(model.Right); 114 | return sql.ToString(); 115 | } 116 | 117 | /// 118 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] WHERE 119 | /// 120 | /// 载有生成信息的Model 121 | /// 查询字符串结果 122 | public string SelectWhere(SqlModel model) 123 | { 124 | StringBuilder sql = new StringBuilder(); 125 | sql.Append(Select(model)); 126 | sql.Append(" WHERE "); 127 | return sql.ToString(); 128 | } 129 | 130 | /// 131 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] WHERE [PrimaryKey]=@PrimaryKey 132 | /// 133 | /// 载有生成信息的Model 134 | /// 查询字符串结果 135 | public string SelectByPrimary(SqlModel model) 136 | { 137 | if (model.PrimaryKey != null) 138 | { 139 | StringBuilder sql = new StringBuilder(); 140 | sql.Append(SelectWhere(model)); 141 | sql.Append(model.Left); 142 | sql.Append(model.PrimaryKey); 143 | sql.Append(model.Right); 144 | sql.Append("=@"); 145 | sql.Append(model.PrimaryKey); 146 | return sql.ToString(); 147 | } 148 | return null; 149 | } 150 | 151 | /// 152 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] WHERE [PrimaryKey] IN @keys 153 | /// 154 | /// 载有生成信息的Model 155 | /// 查询字符串结果 156 | public string SelectIn(SqlModel model) 157 | { 158 | StringBuilder sql = new StringBuilder(); 159 | sql.Append(SelectWhere(model)); 160 | sql.Append(model.Left); 161 | sql.Append(model.PrimaryKey); 162 | sql.Append(model.Right); 163 | sql.Append(" IN @keys"); 164 | return sql.ToString(); 165 | } 166 | 167 | /// 168 | /// 根据model信息生成 SELECT [member1],[member2]... FROM [TableName] WHERE [condition1]=@condition,[condition2]=@condition2..... 169 | /// 170 | /// 载有生成信息的Model 171 | /// 需要匹配的成员集合 172 | /// 查询字符串结果 173 | public string SelectWithCondition(SqlModel model, params string[] conditions) 174 | { 175 | var select = Select(model); 176 | StringBuilder sql = new StringBuilder(select); 177 | ConditionTemplate template = new ConditionTemplate(); 178 | sql.Append(template.Condition(model, conditions)); 179 | return sql.ToString(); 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /Vasily/Vasily.Template/UpdateTemplate.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Vasily.Model; 3 | 4 | namespace Vasily 5 | { 6 | public class UpdateTemplate 7 | { 8 | /// 9 | /// 根据model信息生成 UPDATE [TableName] SET([member1]=@member1,[member2]...=@member2...) 10 | /// 11 | /// 载有生成信息的Model 12 | /// 更新字符串结果 13 | public string Update(SqlModel model) 14 | { 15 | var temp_model = model.ModelWithoutPrimary(); 16 | 17 | StringBuilder update = new StringBuilder(40); 18 | 19 | foreach (var item in temp_model.Members) 20 | { 21 | update.Append(temp_model.Left); 22 | if (temp_model.ColFunction != null) 23 | { 24 | update.Append(temp_model.ColFunction(item)); 25 | } 26 | else 27 | { 28 | update.Append(item); 29 | } 30 | update.Append(temp_model.Right); 31 | 32 | update.Append("=@"); 33 | if (temp_model.FilterFunction != null) 34 | { 35 | update.Append(temp_model.FilterFunction(item)); 36 | } 37 | else 38 | { 39 | update.Append(item); 40 | } 41 | 42 | update.Append(','); 43 | } 44 | 45 | StringBuilder sql = new StringBuilder(60); 46 | if (update.Length > 0) 47 | { 48 | update.Length -= 1; 49 | sql.Append("UPDATE "); 50 | sql.Append(temp_model.Left); 51 | sql.Append(temp_model.TableName); 52 | sql.Append(temp_model.Right); 53 | sql.Append(" SET "); 54 | sql.Append(update); 55 | //sql.Append(" WHERE "); 56 | } 57 | 58 | return sql.ToString(); 59 | } 60 | 61 | 62 | /// 63 | /// 根据model信息生成 UPDATE [TableName] SET([member1]=@member1,[member2]...=@member2...) WHERE 64 | /// 65 | /// 载有生成信息的Model 66 | /// 更新字符串结果 67 | public string UpdateWhere(SqlModel model) 68 | { 69 | StringBuilder sql = new StringBuilder(Update(model)); 70 | sql.Append(" WHERE "); 71 | return sql.ToString(); 72 | } 73 | 74 | /// 75 | /// 根据model信息生成 UPDATE [TableName] SET([member1]=@member1,[member2]...=@member2...) WHERE PrimaryKey=@PrimaryKe 76 | /// 77 | /// 载有生成信息的Model 78 | /// 更新字符串结果 79 | public string UpdateByPrimary(SqlModel model) 80 | { 81 | if (model.PrimaryKey != null) 82 | { 83 | StringBuilder sql = new StringBuilder(); 84 | sql.Append(UpdateWhere(model)); 85 | sql.Append(model.Left); 86 | sql.Append(model.PrimaryKey); 87 | sql.Append(model.Right); 88 | sql.Append("=@"); 89 | sql.Append(model.PrimaryKey); 90 | return sql.ToString(); 91 | } 92 | return null; 93 | } 94 | 95 | 96 | /// 97 | /// 根据model信息生成 UPDATE [TableName] SET([member1]=@member1,[member2]...=@member2...) WHERE [condition1]=@condition,[condition2]=@condition2..... 98 | /// 99 | /// 载有生成信息的Model 100 | /// 需要匹配的成员集合 101 | /// 更新字符串结果 102 | public string UpdateWithCondition(SqlModel model, params string[] conditions) 103 | { 104 | var select = Update(model); 105 | StringBuilder sql = new StringBuilder(select); 106 | ConditionTemplate template = new ConditionTemplate(); 107 | sql.Append(template.Condition(model, conditions)); 108 | return sql.ToString(); 109 | } 110 | 111 | 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /Vasily/Vasily.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0; 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Vasily/Vasily.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | -------------------------------------------------------------------------------- /Vasily/VasilyRunner.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Concurrent; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Threading.Tasks; 5 | using Vasily.Engine; 6 | 7 | namespace System 8 | { 9 | public class VasilyRunner 10 | { 11 | public static ConcurrentDictionary RelationExtentsionTyps; 12 | public static bool UseParallel; 13 | static VasilyRunner() 14 | { 15 | UseParallel = true; 16 | RelationExtentsionTyps = new ConcurrentDictionary(); 17 | } 18 | /// 19 | /// 开局必须调用的函数 20 | /// 21 | /// 如果自己有特殊接口,那么可以写自己的接口名 22 | public static void Run(params string[] interfaceNames) 23 | { 24 | if (interfaceNames.Length==0) 25 | { 26 | interfaceNames = new string[] { "IVasilyNormal" }; 27 | } 28 | List types = new List(); 29 | Assembly assmbly = Assembly.GetEntryAssembly(); 30 | if (assmbly == null) { return; } 31 | IEnumerator typeCollection = assmbly.ExportedTypes.GetEnumerator(); 32 | Type temp_Type = null; 33 | while (typeCollection.MoveNext()) 34 | { 35 | temp_Type = typeCollection.Current; 36 | if (temp_Type.IsClass && !temp_Type.IsAbstract) 37 | { 38 | var temp_Name = temp_Type.Name.Split('-')[0]; 39 | if (!RelationExtentsionTyps.ContainsKey(temp_Name)) 40 | { 41 | RelationExtentsionTyps[temp_Name] = temp_Type; 42 | } 43 | for (int i = 0; i < interfaceNames.Length; i+=1) 44 | { 45 | if (temp_Type.GetInterface(interfaceNames[i]) != null) 46 | { 47 | types.Add(temp_Type); 48 | } 49 | } 50 | 51 | } 52 | } 53 | if (UseParallel) 54 | { 55 | Parallel.ForEach(types, (element) => 56 | { 57 | bool IsNormal = element.GetInterface("IVasilyNormal") != null; 58 | if (IsNormal) 59 | { 60 | SqlNormalMaker analysis = new SqlNormalMaker(element); 61 | } 62 | }); 63 | } 64 | else 65 | { 66 | foreach (var item in types) 67 | { 68 | bool IsNormal = item.GetInterface("IVasilyNormal") != null; 69 | if (IsNormal) 70 | { 71 | SqlNormalMaker analysis = new SqlNormalMaker(item); 72 | } 73 | } 74 | } 75 | 76 | } 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /VasilyDemo/Demo_Connector.cs: -------------------------------------------------------------------------------- 1 | using System.Data; 2 | using System.Data.SqlClient; 3 | using Vasily; 4 | 5 | namespace VasilyDemo 6 | { 7 | class Demo_Connector 8 | { 9 | public void Demo() 10 | { 11 | //添加一个SqlServer驱动的读写字符串 12 | //key为"key:sql" 13 | //连接字符串为"连接字符串" 14 | Connector.Add("key:sql1", "连接字符串"); 15 | Connector.Add("key:sql2", "写-连接字符串","读-连接字符串"); 16 | Connector.Add("key:sql2", "写-连接字符串", "读-连接字符串"); 17 | 18 | //获取"key:sql"的连接初始化器 19 | var creator = Connector.Initor("key:sql1"); 20 | var reader = Connector.ReadInitor("key:sql1"); 21 | var writter = Connector.WriteInitor("key:sql2"); 22 | 23 | //获取连接委托 24 | DbCreator read = creator.Read; 25 | DbCreator write = creator.Write; 26 | 27 | //创建连接 28 | IDbConnection r_connection = read(); 29 | IDbConnection w_connection = write(); 30 | 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /VasilyDemo/Demo_RelationSql.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | using VasilyDemo.Entities; 4 | 5 | namespace VasilyDemo 6 | { 7 | class Demo_RelationSql 8 | { 9 | public static void Start() 10 | { 11 | VasilyRunner.Run(); 12 | 13 | Console.WriteLine(RelationSql.Table); 14 | //table_relation 15 | 16 | Console.WriteLine(RelationSql.Primary); 17 | //rid 18 | 19 | 20 | Console.WriteLine(RelationSql.AddFromSource); 21 | //INSERT INTO [table_relation] ([rid],[one_id],[parent_id])VALUES(@rid, @oid, @rid) 22 | 23 | Console.WriteLine(RelationSql.AddFromTable); 24 | //INSERT INTO [table_relation] ([rid],[one_id],[parent_id])VALUES(@rid, @one_id, @parent_id) 25 | 26 | Console.WriteLine(RelationSql.DeleteAftFromSource); 27 | //DELETE FROM [table_relation] WHERE [one_id] = @oid AND [parent_id] = @rid 28 | 29 | Console.WriteLine(RelationSql.DeleteAftFromTable); 30 | //DELETE FROM [table_relation] WHERE [one_id] = @one_id AND [parent_id] = @parent_id 31 | 32 | Console.WriteLine(RelationSql.DeletePreFromSource); 33 | //DELETE FROM [table_relation] WHERE [three_id] = @tid 34 | 35 | Console.WriteLine(RelationSql.DeletePreFromTable); 36 | //DELETE FROM [table_relation] WHERE [three_id] = @three_id 37 | 38 | 39 | Console.WriteLine(RelationSql.GetFromSource); 40 | //SELECT [three_id] FROM [table_relation] WHERE [one_id] = @oid AND [parent_id] = @rid 41 | 42 | Console.WriteLine(RelationSql.GetFromTable); 43 | //SELECT [three_id] FROM [table_relation] WHERE [one_id] = @one_id AND [parent_id] = @parent_id 44 | 45 | Console.WriteLine(RelationSql.ModifyFromSource); 46 | //UPDATE [table_relation] SET [three_id] = @tid WHERE [one_id] = @oid AND [parent_id] = @rid 47 | 48 | Console.WriteLine(RelationSql.ModifyFromTable); 49 | //UPDATE [table_relation] SET [three_id] = @three_id WHERE [one_id] = @one_id AND [parent_id] = @parent_id 50 | 51 | 52 | //操作对应的是DapperWrapper 53 | DapperWrapper dapper = new DapperWrapper("key"); 54 | 55 | 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /VasilyDemo/Demo_RelationSql_Driver.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using VasilyDemo.Entities; 3 | 4 | namespace VasilyDemo 5 | { 6 | class Demo_RelationSql_Driver 7 | { 8 | public static void Start() 9 | { 10 | One one = new One(); 11 | Two two = new Two(); 12 | Three three = new Three(); 13 | Two_Parent parent = new Two_Parent(); 14 | 15 | //以实体类进行操作 16 | DapperWrapper dapper1 = new DapperWrapper("key"); 17 | 18 | dapper1.SourceGet(one, two); 19 | dapper1.SourceGets(one, two); 20 | dapper1.SourceAdd(three, one, two); 21 | dapper1.SourcePreDelete(three); 22 | dapper1.SourceAftDelete(one, two); 23 | dapper1.SourceModify(three, one, two); 24 | 25 | dapper1.TableGet(one.oid, two.rid); 26 | 27 | //以值进行操作 28 | 29 | DapperWrapper dapper2 = new DapperWrapper("key"); 30 | dapper2.TableGet(one.oid); 31 | dapper2.TableGets(one.oid); 32 | dapper2.TableAdd(three.tid,one.oid); 33 | dapper2.TablePreDelete(three.tid); 34 | dapper2.TableAftDelete(one.oid); 35 | dapper2.TableModify(three.tid, one.oid); 36 | 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /VasilyDemo/Demo_Sql.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Vasily; 5 | using VasilyDemo.Entities; 6 | 7 | namespace VasilyDemo 8 | { 9 | class Demo_Sql 10 | { 11 | public static void Start() 12 | { 13 | VasilyRunner.Run(); 14 | 15 | Console.WriteLine(SqlEntity.Table); 16 | //table_one 17 | 18 | Console.WriteLine(SqlEntity.Primary); 19 | //oid 20 | 21 | Console.WriteLine(SqlEntity.SelectAll); 22 | //SELECT * FROM [table_one] 23 | 24 | Console.WriteLine(SqlEntity.SelectAllByPrimary); 25 | //SELECT * FROM [table_one] WHERE [oid] = @oid 26 | 27 | Console.WriteLine(SqlEntity.SelectAllIn); 28 | //SELECT * FROM [table_one] WHERE [oid] IN @keys 29 | 30 | Console.WriteLine(SqlEntity.SelectAllWhere); 31 | //SELECT * FROM [table_one] WHERE 32 | 33 | 34 | Console.WriteLine(SqlEntity.UpdateAllByPrimary); 35 | //UPDATE [table_one] SET [name]=@name,[create_time]=@create_time,[update_time]=@update_time,[age]=@age,[student_id]=@student_id WHERE [oid]=@oid 36 | 37 | Console.WriteLine(SqlEntity.UpdateAllWhere); 38 | //UPDATE [table_one] SET [name]=@name,[create_time]=@create_time,[update_time]=@update_time,[age]=@age,[student_id]=@student_id WHERE 39 | 40 | 41 | Console.WriteLine(SqlEntity.DeleteByPrimary); 42 | //DELETE FROM [table_one] WHERE [oid] = @oid 43 | 44 | Console.WriteLine(SqlEntity.DeleteWhere); 45 | //DELETE FROM [table_one] WHERE 46 | 47 | 48 | Console.WriteLine(SqlEntity.InsertAll); 49 | //INSERT INTO [table_one] ([name],[create_time],[update_time],[age],[student_id])VALUES(@name, @create_time, @update_time, @age, @student_id) 50 | 51 | Console.WriteLine(SqlEntity.RepeateCount); 52 | //SELECT COUNT(*) FROM [table_one] WHERE [student_id] = @student_id 53 | 54 | Console.WriteLine(SqlEntity.RepeateEntities); 55 | //SELECT * FROM [table_one] WHERE [student_id] = @student_id 56 | Console.WriteLine(SqlEntity.RepeateId); 57 | //SELECT [oid] FROM [table_one] WHERE [student_id] = @student_id 58 | 59 | Console.WriteLine(SqlEntity.SelectCount); 60 | //SELECT Count(*) FROM [table_one] 61 | Console.WriteLine(SqlEntity.SelectCountWhere); 62 | //SELECT Count(*) FROM [table_one] WHERE 63 | 64 | 65 | //操作对应的是DapperWrapper 66 | One one = new One(); 67 | DapperWrapper dapper = new DapperWrapper("key"); 68 | dapper.IsRepeat(one); 69 | } 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /VasilyDemo/Demo_Sql_Driver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.SqlClient; 3 | using Vasily; 4 | using VasilyDemo.Entities; 5 | 6 | namespace VasilyDemo 7 | { 8 | public class Demo_Sql_Driver 9 | { 10 | public static void Start() 11 | { 12 | VasilyRunner.Run(); 13 | Connector.Add("key","链接字符串"); 14 | Connector.Add("key-wr", "读-链接字符串","写-链接字符串"); 15 | Connector.AddRead("read1", "读-链接字符串"); 16 | Connector.AddWrite("write2", "写-链接字符串"); 17 | 18 | //创建driver的三种方式 19 | //wrapper = wrapper1 = wrapper2 20 | 21 | 22 | DapperWrapper wrapper = new DapperWrapper("key"); 23 | DapperWrapper wrapper1 = "key"; 24 | var wrapper2 = DapperWrapper.UseKey("key"); 25 | 26 | //wrapper4 = wrapper5 = wrapper6 = wrapper7 27 | DapperWrapper wrapper4 = new DapperWrapper("read1", "write2"); 28 | DapperWrapper wrapper5 = "key-wr | write2 "; 29 | var wrapper6 = DapperWrapper.UseKey("key-wr", "write2"); 30 | var wrapper7 = DapperWrapper.UseKey("key-wr"); 31 | 32 | 33 | 34 | One one = new One(); 35 | One one1 = new One(); 36 | One one2 = new One(); 37 | 38 | 39 | //两种调用方式 40 | 41 | //指定操作方式,RequestType赋值一次即可。 42 | //RequestType默认为 Complete; 43 | 44 | wrapper.GetAll(); 45 | 46 | //使用属性调用 47 | 48 | //获取所有元素 49 | wrapper.GetAll(); 50 | wrapper.GetByPrimary(one); 51 | wrapper.GetsIn(1, 2, 3, 4); 52 | wrapper.GetIn(1); 53 | wrapper.IsRepeat(one); 54 | wrapper.NoRepeateAdd(one); 55 | wrapper.GetNoRepeateId(one); 56 | wrapper.GetRepeates(one); 57 | wrapper.ModifyByPrimary(one,one1,one2); 58 | wrapper.Add(one, one1, one2); 59 | wrapper.SingleDeleteByPrimary(1); 60 | wrapper.EntitiesDeleteByPrimary(one, one1, one2); 61 | 62 | //SafeInsert = NoRepeateInsert + GetNoRepeateId 63 | wrapper.SafeAdd(one); 64 | 65 | 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /VasilyDemo/Demo_Union.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.Engine; 3 | using Vasily.VP; 4 | using VasilyDemo.Entities; 5 | 6 | namespace VasilyDemo 7 | { 8 | public class Demo_Union 9 | { 10 | SqlCondition condition; 11 | public Demo_Union() 12 | { 13 | SqlMaker package = new SqlMaker(); 14 | condition = new SqlCondition(); 15 | 16 | } 17 | [BenchmarkDotNet.Attributes.Benchmark] 18 | public void TestUnion() 19 | { 20 | var result = SqlCollection.Union(SqlEntity.SelectAllWhere + (condition > "oid").Full, "table1", "table2", "table3"); 21 | } 22 | [BenchmarkDotNet.Attributes.Benchmark] 23 | public void TestFull() 24 | { 25 | var result = SqlEntity.SelectAllWhere + (condition > "oid").Full; 26 | } 27 | [BenchmarkDotNet.Attributes.Benchmark] 28 | public void TestConditon() 29 | { 30 | var result =(condition > "oid").Full; 31 | } 32 | //[BenchmarkDotNet.Attributes.Benchmark] 33 | //public void TestScript() 34 | //{ 35 | // string test = "c<=oid&c==name|c!= create_time^c+oid- create_time^(3,10)"; 36 | // string result = test.Condition(test).Full; 37 | //} 38 | //[BenchmarkDotNet.Attributes.Benchmark] 39 | //public void TestScriptCache() 40 | //{ 41 | // string test = "c!= create_time^c+oid- create_time^(3,10)"; 42 | // string result = test.Condition(test).Full; 43 | // string cache = test.Condition(test).Full; 44 | // cache = test.Condition(test).Full; 45 | // cache = test.Condition(test).Full; 46 | //} 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /VasilyDemo/Entities/City.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | 4 | namespace VasilyDemo.Entities 5 | { 6 | [Table("tb_city", SqlType.MySql)] 7 | public class City:IVasilyNormal 8 | { 9 | [PrimaryKey] 10 | [Relation(typeof(City))] 11 | public int id { get; set; } 12 | public string name { get; set; } 13 | 14 | 15 | //让parent_id指向自身 16 | [Relation(typeof(City_Anyname), "id")] 17 | public int parent_id { get; set; } 18 | } 19 | 20 | public class City_Anyname { } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /VasilyDemo/Entities/One.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | 4 | namespace VasilyDemo.Entities 5 | { 6 | [Table("table_one",SqlType.MsSql)] 7 | public class One:IVasilyNormal 8 | { 9 | [PrimaryKey] 10 | public int oid { get; set; } 11 | 12 | public string name { get; set; } 13 | 14 | public int create_time { get; set; } 15 | 16 | public int update_time { get; set; } 17 | 18 | public int age { get; set; } 19 | 20 | [NoRepeate] 21 | public long student_id { get; set; } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /VasilyDemo/Entities/SchoolClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | 4 | namespace VasilyDemo.Entities 5 | { 6 | [Table("tb_class", SqlType.MySql)] 7 | public class SchoolClass : IVasilyNormal 8 | { 9 | [PrimaryKey] 10 | public int cid { get; set; } 11 | 12 | 13 | public string name { get; set; } 14 | 15 | 16 | [Column("create time")] 17 | public int create_time { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /VasilyDemo/Entities/Student.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | 4 | namespace VasilyDemo.Entities 5 | { 6 | [Table("tb_student", SqlType.MySql)] 7 | public class Student : IVasilyNormal 8 | { 9 | [PrimaryKey] 10 | public int oid { get; set; } 11 | 12 | 13 | [NoRepeate] 14 | public long student_id { get; set; } 15 | 16 | 17 | public int age { get; set; } 18 | public string name { get; set; } 19 | 20 | 21 | [Column("create time")] 22 | public int create_time { get; set; } 23 | [Column("last time")] 24 | public int update_time { get; set; } 25 | 26 | 27 | [Ignore] 28 | public string[] Children; 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /VasilyDemo/Entities/StudentAndClass.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | 3 | namespace VasilyDemo.Entities 4 | { 5 | [Table("tb_student_class", SqlType.MySql)] 6 | public class StudentAndClass 7 | { 8 | [PrimaryKey] 9 | public int rid { get; set; } 10 | 11 | 12 | //若不传"cid", 则默认使用Class的主键 13 | [Relation(typeof(SchoolClass), "cid")] 14 | public int class_id { get; set; } 15 | 16 | 17 | //student_id并没有对应学生的id,而是对应了学生表里student_id 18 | [Relation(typeof(Student), "student_id")] 19 | public int student_id { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /VasilyDemo/Entities/Two.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | 4 | namespace VasilyDemo.Entities 5 | { 6 | [Table("table_relation", SqlType.MsSql)] 7 | public class Two 8 | { 9 | [PrimaryKey] 10 | [Relation(typeof(Two))] 11 | public int rid { get; set; } 12 | 13 | [Relation(typeof(One))] 14 | public int one_id { get; set; } 15 | 16 | [Relation(typeof(Three))] 17 | public int three_id { get; set; } 18 | 19 | [Relation(typeof(Two_Parent), "rid")] 20 | public int parent_id { get; set; } 21 | 22 | } 23 | 24 | public class Three 25 | { 26 | [PrimaryKey] 27 | public int tid { get; set; } 28 | } 29 | 30 | public class Two_Parent { } 31 | } 32 | -------------------------------------------------------------------------------- /VasilyDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using BenchmarkDotNet.Running; 2 | using System; 3 | using System.Data.SqlClient; 4 | using Vasily; 5 | using Vasily.Engine; 6 | using VasilyDemo.Entities; 7 | 8 | namespace VasilyDemo 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | /* 15 | Connector.Add("key:sql1", "连接字符串"); 16 | Connector.Add("key:sql2", "写-连接字符串", "读-连接字符串"); 17 | 18 | DapperWrapper wrapper = new DapperWrapper("key:sql2"); 19 | 20 | //重试3次 21 | //取第1,3次的结果 22 | int retry_count = 3; 23 | int[] take_errors = new int[] { 1, 3}; 24 | 25 | //准备实体 26 | One entity = new One(); 27 | entity.age = 100; 28 | entity.name = "小玉"; 29 | 30 | //使用事务 31 | wrapper.TransactionRetry((read_connection, write_connection) => 32 | { 33 | //wrapper.SafeAdd(check_repeate); Or 34 | 35 | if (!wrapper.IsRepeat(entity)) 36 | { 37 | wrapper.Add(entity); 38 | } 39 | else 40 | { 41 | //wrapper.ModifyByPrimary(check_repeate); 42 | wrapper.Modify( 43 | item => item == "age" & item == "name", 44 | entity 45 | ); 46 | } 47 | 48 | }, retry_count,take_errors); 49 | 50 | 51 | wrapper.Gets(item => item > "view" ^ item - "id" ^(10, 5),null); 52 | 53 | //Demo_Sql.Start(); 54 | 55 | //Demo_RelationSql.Start(); 56 | 57 | 58 | //BenchmarkRunner.Run();*/ 59 | //SqlMaker package = new SqlMaker(); 60 | //var fields = typeof(SqlEntity).GetFields(); 61 | //foreach (var item in fields) 62 | //{ 63 | // Console.WriteLine(item.Name + "\t:\t"+ item.GetValue(null)); 64 | //} 65 | //new SqlMaker(); 66 | //new SqlRelationMaker(typeof(RelationSql)); 67 | //fields = typeof(RelationSql).GetFields(); 68 | //foreach (var item in fields) 69 | //{ 70 | // Console.WriteLine(item.Name + "\t:\t" + item.GetValue(null)); 71 | //} 72 | VasilyRunner.Run(); 73 | new SqlRelationMaker(typeof(RelationSql)); 74 | var fields = typeof(RelationSql).GetFields(); 75 | foreach (var item in fields) 76 | { 77 | Console.WriteLine(item.Name + "\t:\t" + item.GetValue(null)); 78 | } 79 | Console.ReadKey(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /VasilyDemo/VasilyDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /VasilyDemo/VasilyDemo.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /VasilyHttpDemo/Controllers/StudentController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Mvc; 7 | using VasilyHttpDemo.Entities; 8 | 9 | namespace VasilyHttpDemo.Controllers 10 | { 11 | [Route("api/[controller]")] 12 | [ApiController] 13 | public class StudentController : VPReadAndWriteController 14 | { 15 | public StudentController() : base("School") { } 16 | 17 | [HttpGet] 18 | public ReturnResult GetAll() 19 | { 20 | return Result(driver.GetAll()); 21 | } 22 | [HttpGet("test")] 23 | public ReturnResult Test() 24 | { 25 | return Result(1); 26 | } 27 | [HttpGet("test2")] 28 | public int Test2() 29 | { 30 | return 1; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /VasilyHttpDemo/Controllers/TestVasilyController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Vasily.VP; 3 | 4 | namespace VasilyHttpDemo.Controllers 5 | { 6 | [Route("api/[controller]")] 7 | [ApiController] 8 | public class TestVasilyController : VasilyController 9 | { 10 | public TestVasilyController():base("key"){} 11 | [HttpGet] 12 | public ReturnPageResult GetCount() 13 | { 14 | //按照id降序排列,取第10页的前10条 15 | //return GetsPageResult(c.Condition(c - "id" ^(10,10)) ); 16 | 17 | //从前端传过来一个查询JSON格式 18 | /*{ 19 | value:{ 20 | id:10000 21 | }, 22 | sql:"c>id ^c - id ^(3,10)", 23 | unions:[ 24 | "tb_table1", 25 | "tb_table2" 26 | ] 27 | }*/ 28 | 29 | //模拟POST 30 | 31 | VasilyProtocal vp = new VasilyProtocal(); 32 | vp.Script = "c>id ^c - id ^(3,10)"; 33 | vp.Instance = new TestEntity() { id = 1000 }; 34 | 35 | UseUnion("td_teacher1", "td_teacher2"); 36 | return GetsPageResult(vp); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /VasilyHttpDemo/Entities/ShcoolClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Vasily; 6 | 7 | namespace VasilyHttpDemo.Entities 8 | { 9 | [Table("class")] 10 | public class ShcoolClass 11 | { 12 | [PrimaryKey] 13 | public int id; 14 | public string name; 15 | public int count; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /VasilyHttpDemo/Entities/Student.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Vasily; 6 | 7 | namespace VasilyHttpDemo.Entities 8 | { 9 | [Table("student",SqlType.MySql)] 10 | public class Student:IVasilyNormal 11 | { 12 | [PrimaryKey] 13 | public int id { get; set; } 14 | public string name; 15 | public bool sex { get; set; } 16 | [Relation(typeof(ShcoolClass))] 17 | public int class_id; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /VasilyHttpDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace VasilyHttpDemo 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseStartup(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /VasilyHttpDemo/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:64072", 8 | "sslPort": 44323 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/TestVasily", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "VasilyHttpDemo": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/TestVasily", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /VasilyHttpDemo/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.AspNetCore.HttpsPolicy; 8 | using Microsoft.AspNetCore.Mvc; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Logging; 12 | using Microsoft.Extensions.Options; 13 | using MySql.Data.MySqlClient; 14 | 15 | namespace VasilyHttpDemo 16 | { 17 | public class Startup 18 | { 19 | public Startup(IConfiguration configuration) 20 | { 21 | Configuration = configuration; 22 | } 23 | 24 | public IConfiguration Configuration { get; } 25 | 26 | // This method gets called by the runtime. Use this method to add services to the container. 27 | public void ConfigureServices(IServiceCollection services) 28 | { 29 | services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 30 | services.AddVasily(item => 31 | { 32 | item.Add("key", "Database=tmp_cb2016;Data Source=192.168.30.225;Port=3306;User Id=root;Password=123321;Charset=utf8;SslMode = none;"); 33 | item.Add("School", "Server=192.168.62.128;Database=test; User=test;Password=123456;"); 34 | }); 35 | } 36 | 37 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 38 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 39 | { 40 | if (env.IsDevelopment()) 41 | { 42 | app.UseDeveloperExceptionPage(); 43 | } 44 | else 45 | { 46 | app.UseHsts(); 47 | } 48 | app.UseStaticFiles(); 49 | app.UseHttpsRedirection(); 50 | app.UseMvc(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /VasilyHttpDemo/TestEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Vasily; 6 | 7 | namespace VasilyHttpDemo 8 | { 9 | [Table("td_tmp_article_msg",SqlType.MySql)] 10 | public class TestEntity:IVasilyNormal 11 | { 12 | [PrimaryKey] 13 | public int id { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /VasilyHttpDemo/VasilyHttpDemo.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /VasilyHttpDemo/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /VasilyHttpDemo/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /VasilyHttpDemo/wwwroot/index.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 测试 7 | 49 | 50 | 51 |
52 | 53 |
54 |
55 | 56 |
57 |
58 | 59 |
60 |
61 | 62 |
63 |
64 | 65 |
66 |
67 | 68 |
69 | 70 |
71 | 72 |
73 | 74 | 75 | -------------------------------------------------------------------------------- /VasilyUT/Entity/Class.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Vasily; 5 | 6 | namespace VasilyUT.Entity 7 | { 8 | [Table("AB",SqlType.MySql)] 9 | public class Class:IVasilyNormal 10 | { 11 | [PrimaryKey] 12 | public int Cid; 13 | public string Other; 14 | } 15 | [Table("AB", SqlType.MySql)] 16 | public class Class1 : IVasilyNormal 17 | { 18 | [PrimaryKey] 19 | public string Name; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /VasilyUT/Entity/Relation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | 4 | namespace VasilyUT.Entity 5 | { 6 | [Table("关系映射表", SqlType.MySql)] 7 | public class Relation : IVasilyNormal 8 | { 9 | [PrimaryKey] 10 | [Relation(typeof(Relation), "Id")] 11 | public int Id; 12 | 13 | [Relation(typeof(Student), "Sid")] 14 | public int StudentId; 15 | 16 | [Relation(typeof(Class))] 17 | public int ClassId; 18 | } 19 | 20 | [Table("关系映射表2", SqlType.MsSql)] 21 | public class Relation2 : IVasilyNormal 22 | { 23 | [PrimaryKey] 24 | [Relation(typeof(Relation2), "Id")] 25 | public int Id; 26 | 27 | [Relation(typeof(Student), "Sid")] 28 | public int StudentId; 29 | 30 | [Relation(typeof(Student1), "Name")] 31 | public int StudentName; 32 | 33 | [Relation(typeof(Class))] 34 | public int ClassId; 35 | 36 | [Relation(typeof(Class1), "Name")] 37 | public int ClassName; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /VasilyUT/Entity/Student.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Vasily; 5 | 6 | namespace VasilyUT.Entity 7 | { 8 | [Table("1",SqlType.MySql)] 9 | public class Student:IVasilyNormal 10 | { 11 | [PrimaryKey] 12 | public int Sid { get; set; } 13 | } 14 | [Table("1")] 15 | public class Student1 : IVasilyNormal 16 | { 17 | [PrimaryKey] 18 | public string Name { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /VasilyUT/Entity/Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Vasily; 5 | 6 | namespace VasilyUT.Entity 7 | { 8 | [Table("Table")] 9 | 10 | public class Test:IVasilyNormal 11 | { 12 | [PrimaryKey] 13 | public int Id; 14 | 15 | [NoRepeate] 16 | public string NoRepeate; 17 | 18 | [Ignore] 19 | public string Ignore1; 20 | 21 | [Ignore] 22 | public string Ignore2; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /VasilyUT/Entity/Test2.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace VasilyUT.Entity 6 | { 7 | public class Test2 8 | { 9 | public int Tid; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /VasilyUT/Program.cs: -------------------------------------------------------------------------------- 1 | using Dapper; 2 | using MySql.Data.MySqlClient; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using Vasily; 7 | using Vasily.Core; 8 | using VasilyUT.Entity; 9 | 10 | namespace VasilyUT 11 | { 12 | class Program 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyCache.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.Core; 3 | using Vasily.Engine; 4 | using Vasily.Model; 5 | using VasilyUT.Entity; 6 | using Xunit; 7 | 8 | namespace VasilyUT 9 | { 10 | public class UnitTest_VasilyCache 11 | { 12 | [Fact(DisplayName = "缓存-SQL生成器Model测试")] 13 | public void TestSelectRelation32() 14 | { 15 | SqlMaker package = new SqlMaker(); 16 | Assert.Equal("Id", SqlModel.PrimaryKey); 17 | Assert.Equal('`', SqlModel.Left); 18 | Assert.Equal('`', SqlModel.Right); 19 | Assert.Equal("关系映射表", SqlModel.TableName); 20 | Assert.NotNull(SqlModel.ColumnMapping); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyConditions.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.Engine; 3 | using Vasily.VP; 4 | using VasilyUT.Entity; 5 | using Xunit; 6 | 7 | namespace VasilyUT 8 | { 9 | public class UnitTest_VasilyConditions 10 | { 11 | 12 | [Fact(DisplayName = "条件模糊查询测试1")] 13 | public void TestLikeCondition() 14 | { 15 | SqlMaker package = new SqlMaker(); 16 | SqlCondition condition = new SqlCondition(); 17 | Assert.Equal("([StudentId] > @StudentId AND [StudentId] LIKE @StudentId)", (condition > "StudentId" & condition % "StudentId").ToString()); 18 | } 19 | [Fact(DisplayName = "条件模糊查询测试2")] 20 | public void TestLikeCondition2() 21 | { 22 | SqlMaker package = new SqlMaker(); 23 | SqlCondition condition = new SqlCondition(); 24 | Assert.Equal("(([StudentId] LIKE @StudentId AND [StudentId] > @StudentId) AND [StudentId] LIKE @StudentId)", ("StudentId" % condition & condition > "StudentId" & condition % "StudentId").ToString()); 25 | } 26 | [Fact(DisplayName = "条件拼接测试1")] 27 | public void TestCondition() 28 | { 29 | SqlMaker package = new SqlMaker(); 30 | SqlCondition condition = new SqlCondition(); 31 | Assert.Equal("[StudentId] > @StudentId", (condition > "StudentId").ToString()); 32 | } 33 | [Fact(DisplayName = "条件拼接测试2")] 34 | public void TestCondition2() 35 | { 36 | SqlMaker package = new SqlMaker(); 37 | SqlCondition condition = new SqlCondition(); 38 | Assert.Equal("([StudentId] > @StudentId OR [ClassId] <> @ClassId)", (condition > "StudentId" | condition != "ClassId").ToString()); 39 | } 40 | [Fact(DisplayName = "条件拼接测试3")] 41 | public void TestCondition3() 42 | { 43 | SqlMaker package = new SqlMaker(); 44 | SqlCondition c = new SqlCondition(); 45 | Assert.Equal( 46 | 47 | "(([StudentId] > @StudentId OR [ClassId] = @ClassId) AND [ClassName] <> @ClassName)", 48 | 49 | ((c > "StudentId" | c == "ClassId") & c != "ClassName").ToString() 50 | 51 | ); 52 | } 53 | 54 | [Fact(DisplayName = "条件拼接+分页测试1")] 55 | public void TestPageCondition1() 56 | { 57 | SqlMaker package = new SqlMaker(); 58 | SqlCondition c = new SqlCondition(); 59 | VasilyProtocal vp = ((c > "StudentId" | c == "ClassId") & c != "ClassName") ^ (2, 10); 60 | vp.Instance = new { StudentId = 1, ClassId = 2, ClassName = "abc" }; 61 | 62 | Assert.Equal( 63 | 64 | "(([StudentId] > @StudentId OR [ClassId] = @ClassId) AND [ClassName] <> @ClassName) OFFSET 10 ROW FETCH NEXT 10 rows only", 65 | 66 | vp.Full 67 | 68 | ); 69 | } 70 | [Fact(DisplayName = "条件拼接+分页测试2")] 71 | public void TestPageCondition2() 72 | { 73 | SqlMaker package = new SqlMaker(); 74 | SqlCondition c = new SqlCondition(); 75 | 76 | 77 | VasilyProtocal vp = c > "StudentId" | c == "ClassId" & c != "Id" ^ (2, 10); 78 | vp.Instance = new { StudentId = 1, ClassId = 2, ClassName = "abc" }; 79 | 80 | 81 | Assert.Equal( 82 | 83 | "(`StudentId` > @StudentId OR (`ClassId` = @ClassId AND `Id` <> @Id)) LIMIT 10,10", 84 | 85 | vp.Full 86 | 87 | ); 88 | } 89 | [Fact(DisplayName = "条件拼接+排序测试1")] 90 | public void TestOrderCondition2() 91 | { 92 | SqlMaker package = new SqlMaker(); 93 | SqlCondition c = new SqlCondition(); 94 | Assert.Equal( 95 | 96 | "(([StudentId] > @StudentId OR [ClassId] = @ClassId) AND [ClassName] <> @ClassName) ORDER BY [StudentId] ASC", 97 | 98 | //----------------------------条件----------------排序链接--升序------------ 99 | // ↓ ↓ 100 | ((c > "StudentId" | c == "ClassId") & c != "ClassName" ^ c + "StudentId").ToString() 101 | 102 | ); 103 | } 104 | [Fact(DisplayName = "条件拼接+排序测试2")] 105 | public void TestPageCondition3() 106 | { 107 | SqlMaker package = new SqlMaker(); 108 | SqlCondition c = new SqlCondition(); 109 | Assert.Equal( 110 | 111 | "(([StudentId] > @StudentId OR [ClassId] = @ClassId) AND [ClassName] <> @ClassName) ORDER BY [StudentId] ASC,[ClassId] DESC", 112 | //升序-----------降序-----排序链接-----------------条件---------------------------- 113 | //↓ ↓ ↓ 114 | (c + "StudentId" - "ClassId" ^(c > "StudentId" | c == "ClassId") & c != "ClassName").ToString() 115 | 116 | ); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyConnectors.cs: -------------------------------------------------------------------------------- 1 | using MySql.Data.MySqlClient; 2 | using System; 3 | using Vasily; 4 | using Xunit; 5 | 6 | namespace VasilyUT 7 | { 8 | 9 | public class UnitTest_VasilyConnectors 10 | { 11 | [Fact(DisplayName = "读-初始化器测试")] 12 | public void TestRead() 13 | { 14 | Connector.Add( 15 | "unit", 16 | "database=Read", 17 | "database=Write" 18 | ); 19 | 20 | DbCreator creator = Connector.ReadInitor("unit"); 21 | 22 | Assert.NotNull(creator); 23 | Assert.Equal("database=Read", creator().ConnectionString); 24 | } 25 | [Fact(DisplayName = "写-初始化器测试")] 26 | public void TestWrite() 27 | { 28 | Connector.Add( 29 | "unit", 30 | "database=Read", 31 | "database=Write" 32 | ); 33 | 34 | DbCreator creator = Connector.WriteInitor("unit"); 35 | 36 | Assert.NotNull(creator); 37 | Assert.Equal("database=Write", creator().ConnectionString); 38 | } 39 | 40 | [Fact(DisplayName = "读写-初始化器测试")] 41 | public void TestReadAndWrite() 42 | { 43 | Connector.Add( 44 | "unit", 45 | "database=Test" 46 | ); 47 | 48 | var creator = Connector.Initor("unit"); 49 | Assert.Equal("database=Test", creator.Read().ConnectionString); 50 | Assert.Equal("database=Test", creator.Write().ConnectionString); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyReflectors.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Reflection; 4 | using Vasily; 5 | using VasilyUT.Entity; 6 | using Xunit; 7 | using Vasily.Engine.Extensions; 8 | using Vasily.Engine.Utils; 9 | 10 | namespace VasilyUT 11 | { 12 | public class UnitTest_VasilyReflectors 13 | { 14 | public class TestType 15 | { 16 | public int? test_field; 17 | public int? test_property { get; set; } 18 | } 19 | 20 | [Fact(DisplayName = "语法糖扩展")] 21 | public void TestTypeExtension() 22 | { 23 | var field = typeof(TestType).GetField("test_field"); 24 | var property = typeof(TestType).GetProperty("test_property"); 25 | Assert.True(field.FieldType.IsNullable()); 26 | Assert.True(property.PropertyType.IsNullable()); 27 | Assert.Equal(typeof(int), property.PropertyType.GetNullableType()); 28 | Assert.Equal(typeof(int), field.FieldType.GetNullableType()); 29 | } 30 | 31 | [Fact(DisplayName ="单成员单标签实例")] 32 | public void TestSaSiSm() 33 | { 34 | AttrOperator reflector = new AttrOperator(typeof(Test)); 35 | var result = reflector.AttrAndMember(); 36 | Assert.NotNull(result.Instance); 37 | Assert.Equal(result.Member, typeof(Test).GetMember("Id")[0]); 38 | } 39 | 40 | [Fact(DisplayName = "单标签多成员")] 41 | public void TestSaMm() 42 | { 43 | AttrOperator reflector = new AttrOperator(typeof(Test)); 44 | var result =new List(reflector.Members()); 45 | Assert.Equal(2,result.Count()); 46 | Assert.Equal(result.Find(item=> { return item.Name == "Ignore1"; }),typeof(Test).GetMember("Ignore1")[0]); 47 | Assert.Equal(result.Find(item => { return item.Name == "Ignore2"; }), typeof(Test).GetMember("Ignore2")[0]); 48 | } 49 | 50 | [Fact(DisplayName = "单标签实例")] 51 | public void TestSaSi() 52 | { 53 | AttrOperator reflector = new AttrOperator(typeof(Test)); 54 | var result = reflector.Instance(); 55 | Assert.Equal("Table",result.Name); 56 | } 57 | 58 | [Fact(DisplayName = "单标签实例")] 59 | public void TestSaSm() 60 | { 61 | AttrOperator reflector = new AttrOperator(typeof(Test)); 62 | var result = reflector.Member(); 63 | Assert.Equal(typeof(Test).GetMember("NoRepeate")[0], result); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyRelationEmit.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.Engine; 3 | using VasilyUT.Entity; 4 | using Xunit; 5 | 6 | namespace VasilyUT 7 | { 8 | public class UnitTest_VasilyRelationEmit 9 | { 10 | 11 | [Fact(DisplayName = "属性值类型Setter/Getter测试")] 12 | public void TestValueProperty() 13 | { 14 | SqlMaker package = new SqlMaker(); 15 | SqlMaker package1 = new SqlMaker(); 16 | Student student = new Student(); 17 | SqlEntity.SetPrimary(student, 1); 18 | Assert.Equal(1, (int)RelationSql.Getters[0](student)); 19 | 20 | } 21 | [Fact(DisplayName = "属性引用类型Setter/Getter测试")] 22 | public void TestRefProperty() 23 | { 24 | SqlMaker package = new SqlMaker(); 25 | SqlMaker package1 = new SqlMaker(); 26 | Student1 student = new Student1(); 27 | SqlEntity.SetPrimary(student, "abc"); 28 | Assert.Equal("abc", (string)RelationSql.Getters[0](student)); 29 | 30 | } 31 | 32 | [Fact(DisplayName = "字段值类型Setter/Getter测试")] 33 | public void TestValueField() 34 | { 35 | SqlMaker package = new SqlMaker(); 36 | SqlMaker package1 = new SqlMaker(); 37 | Class myClass = new Class(); 38 | SqlEntity.SetPrimary(myClass,1); 39 | Assert.Equal(1, (int)RelationSql.Getters[0](myClass)); 40 | 41 | } 42 | [Fact(DisplayName = "字段引用类型Setter/Getter测试")] 43 | public void TestRefField() 44 | { 45 | SqlMaker package = new SqlMaker(); 46 | SqlMaker package1 = new SqlMaker(); 47 | Class1 myClass = new Class1(); 48 | SqlEntity.SetPrimary(myClass, "abc"); 49 | Assert.Equal("abc", (string)RelationSql.Getters[0](myClass)); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyStaticEmit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Vasily; 3 | using Vasily.Engine; 4 | using Vasily.Engine.Utils; 5 | using Xunit; 6 | 7 | namespace VasilyUT 8 | { 9 | 10 | public class UnitTest_VasilyStaticEmit 11 | { 12 | [Fact(DisplayName = "无泛型的Operator")] 13 | public void TesZeroStatic() 14 | { 15 | 16 | var operator1 = new GsOperator(typeof(SqlEntity<>),typeof(int)); 17 | operator1.Set("SelectAll", "MsSqlOne"); 18 | 19 | 20 | var operator2 = new GsOperator(typeof(SqlEntity<>),typeof(string)); 21 | operator2.Set("InsertAll", "MySqlOne"); 22 | 23 | 24 | Assert.Equal("MsSqlOne", SqlEntity.SelectAll); 25 | Assert.Equal("MySqlOne", SqlEntity.InsertAll); 26 | } 27 | [Fact(DisplayName = "一个泛型的Operator")] 28 | public void TestOneStatic() 29 | { 30 | var operator1 = new GsOperator>(typeof(int)); 31 | operator1.Set("SelectAll", "MsSqlOne"); 32 | 33 | 34 | var operator2 = new GsOperator>(typeof(string)); 35 | operator2.Set("SelectAll", "MySqlOne1"); 36 | 37 | 38 | Assert.Equal("MsSqlOne", SqlEntity.SelectAll); 39 | Assert.Equal("MySqlOne1", SqlEntity.SelectAll); 40 | } 41 | 42 | [Fact(DisplayName = "两个泛型的Operator")] 43 | public void TestTwoStatic() 44 | { 45 | var operator1 = new GsOperator,int>(); 46 | operator1.Set("SelectAll", "MsSqlOne"); 47 | 48 | 49 | var operator2 = new GsOperator, string>(); 50 | operator2.Set("InsertAll", "MySqlOne"); 51 | 52 | 53 | Assert.Equal("MsSqlOne", SqlEntity.SelectAll); 54 | Assert.Equal("MySqlOne", SqlEntity.InsertAll); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilySyntaxTree.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Vasily; 5 | using Vasily.Core; 6 | using Vasily.Engine; 7 | using Vasily.VP; 8 | using VasilyUT.Entity; 9 | using Xunit; 10 | 11 | namespace VasilyUT 12 | { 13 | public class UnitTest_VasilySyntaxTree 14 | { 15 | 16 | [Fact(DisplayName = "语法树-优先级解析1")] 17 | public void TestNormalScript() 18 | { 19 | SqlMaker package = new SqlMaker(); 20 | VasilyProtocal vp = "c<=Id&c==StudentName|c!= ClassId^c+Id- ClassId^(3,10)"; 21 | Assert.Equal("(([Id] <= @Id AND [StudentName] = @StudentName) OR [ClassId] <> @ClassId) ORDER BY [Id] ASC,[ClassId] DESC OFFSET 20 ROW FETCH NEXT 10 rows only", 22 | vp.Full); 23 | } 24 | 25 | [Fact(DisplayName = "语法树-优先级解析2")] 26 | public void TestNormalScript1() 27 | { 28 | SqlMaker package = new SqlMaker(); 29 | VasilyProtocal vp = "c<=Id&(c==StudentName|c!= ClassId)^c+Id-ClassId^(3,10)"; 30 | Assert.Equal("([Id] <= @Id AND ([StudentName] = @StudentName OR [ClassId] <> @ClassId)) ORDER BY [Id] ASC,[ClassId] DESC OFFSET 20 ROW FETCH NEXT 10 rows only", 31 | vp.Full); 32 | } 33 | [Fact(DisplayName = "语法树-乱序解析1")] 34 | public void TestNormalScript2() 35 | { 36 | SqlMaker package = new SqlMaker(); 37 | VasilyProtocal vp = "c+Id-ClassId^(3,10) ^c<=Id&(c==StudentName|c!= ClassId)"; 38 | Assert.Equal("([Id] <= @Id AND ([StudentName] = @StudentName OR [ClassId] <> @ClassId)) ORDER BY [Id] ASC,[ClassId] DESC OFFSET 20 ROW FETCH NEXT 10 rows only", 39 | vp.Full); 40 | } 41 | [Fact(DisplayName = "语法树-乱序解析2")] 42 | public void TestNormalScript3() 43 | { 44 | SqlMaker package = new SqlMaker(); 45 | VasilyProtocal vp = "c+Id-ClassId ^ c<=Id&(c==StudentName|c!= ClassId)^(3,10)"; 46 | Assert.Equal("([Id] <= @Id AND ([StudentName] = @StudentName OR [ClassId] <> @ClassId)) ORDER BY [Id] ASC,[ClassId] DESC OFFSET 20 ROW FETCH NEXT 10 rows only", 47 | vp.Full); 48 | } 49 | 50 | [Fact(DisplayName = "语法树-模糊查询解析1")] 51 | public void TestLikeScript1() 52 | { 53 | SqlMaker package = new SqlMaker(); 54 | VasilyProtocal vp = "c+Id-ClassId ^c<=Id&(c==StudentName|c!= ClassId)^(3,10) & c%StudentName"; 55 | Assert.Equal("(([Id] <= @Id AND ([StudentName] = @StudentName OR [ClassId] <> @ClassId)) AND [StudentName] LIKE @StudentName) ORDER BY [Id] ASC,[ClassId] DESC OFFSET 20 ROW FETCH NEXT 10 rows only", 56 | vp.Full); 57 | } 58 | [Fact(DisplayName = "语法树-模糊查询解析2")] 59 | public void TestLikeScript2() 60 | { 61 | SqlMaker package = new SqlMaker(); 62 | VasilyProtocal vp = "c % ClassId ^ c+Id-ClassId & c<=Id&(c==StudentName|c!= ClassId)^(3,10) & c%StudentName"; 63 | Assert.Equal("((([ClassId] LIKE @ClassId AND [Id] <= @Id) AND ([StudentName] = @StudentName OR [ClassId] <> @ClassId)) AND [StudentName] LIKE @StudentName) ORDER BY [Id] ASC,[ClassId] DESC OFFSET 20 ROW FETCH NEXT 10 rows only", 64 | vp.Full); 65 | } 66 | [Fact(DisplayName = "语法树-模糊查询解析3")] 67 | public void TestLikeScript3() 68 | { 69 | SqlMaker package = new SqlMaker(); 70 | VasilyProtocal vp = "c%StudentName ^ c+Id-ClassId & c%ClassId "; 71 | 72 | Assert.Equal("([StudentName] LIKE @StudentName AND [ClassId] LIKE @ClassId) ORDER BY [Id] ASC,[ClassId] DESC", 73 | vp.Full); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyUnion.cs: -------------------------------------------------------------------------------- 1 | using Vasily; 2 | using Vasily.Engine; 3 | using Vasily.VP; 4 | using VasilyUT.Entity; 5 | using Xunit; 6 | 7 | namespace VasilyUT 8 | { 9 | public class UnitTest_VasilyUnion 10 | { 11 | [Fact(DisplayName = "条件+联合语句测试1")] 12 | public void TestUnionCondition1() 13 | { 14 | SqlMaker package = new SqlMaker(); 15 | SqlCondition condition = new SqlCondition(); 16 | var result = SqlCollection.TableUnion(SqlEntity.SelectAllWhere + (condition > "Sid").Full, "table1", "table2", "table3"); 17 | Assert.Equal("(SELECT * FROM `table1` WHERE `Sid` > @Sid) UNION (SELECT * FROM `table2` WHERE `Sid` > @Sid) UNION (SELECT * FROM `table3` WHERE `Sid` > @Sid)", result); 18 | } 19 | [Fact(DisplayName = "条件+联合语句测试2")] 20 | public void TestUnionCondition2() 21 | { 22 | SqlMaker package = new SqlMaker(); 23 | SqlCondition condition = new SqlCondition(); 24 | var result = SqlCollection.Union(SqlEntity.SelectAllWhere + (condition > "Sid").Full); 25 | Assert.Equal("(SELECT * FROM `1` WHERE `Sid` > @Sid)", result); 26 | } 27 | [Fact(DisplayName = "条件+联合语句测试3")] 28 | public void TestUnionCondition3() 29 | { 30 | SqlMaker package = new SqlMaker(); 31 | SqlCondition condition = new SqlCondition(); 32 | var result = SqlCollection.TableIntersect(SqlEntity.SelectAllWhere + (condition > "Sid").Full, "table1", "table2", "table3"); 33 | Assert.Equal("(SELECT * FROM `table1` WHERE `Sid` > @Sid) INTERSECT (SELECT * FROM `table2` WHERE `Sid` > @Sid) INTERSECT (SELECT * FROM `table3` WHERE `Sid` > @Sid)", result); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /VasilyUT/UnitTest_VasilyUniqueId.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using VasilyUT.Entity; 5 | using Xunit; 6 | 7 | namespace VasilyUT 8 | { 9 | public class UnitTest_VasilyUniqueId 10 | { 11 | [Fact(DisplayName = "一打雪花,带你勇闯天涯")] 12 | public void TestId() 13 | { 14 | HashSet hashSet = new HashSet(); 15 | Snowflake.SetNodesInfo(54321, 12345); 16 | for (int i = 0; i < 10; i+=1) 17 | { 18 | long result = Snowflake.NextId; 19 | Assert.DoesNotContain(result, hashSet); 20 | hashSet.Add(result); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /VasilyUT/VasilyUT.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.0 5 | false 6 | 7 | Exe 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | all 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman --------------------------------------------------------------------------------