├── .gitattributes ├── .gitignore ├── Docs ├── 1. quickstart.md ├── 2 入门.md ├── 2.1 安装FreeSql ├── codefirst.md ├── dbfirst.md ├── delete.md ├── expression.md ├── generator.md ├── insert.md ├── select.md └── update.md ├── FreeSql.Tests.PerformanceTests ├── FreeSql.Tests.PerformanceTests.csproj ├── MySqlAdoTest.cs └── g.cs ├── FreeSql.Tests ├── Class1.cs ├── DataAnnotations │ └── FluentTest.cs ├── Extensions │ └── StringExtensionsTest.cs ├── FreeSql.Tests.csproj ├── Generator │ ├── MySqlTemplateGeneratorTest.cs │ ├── PostgreSQLTemplateGeneratorTest.cs │ └── SqlServerTemplateGeneratorTest.cs ├── MySql │ ├── Curd │ │ ├── MySqlDeleteTest.cs │ │ ├── MySqlInsertTest.cs │ │ ├── MySqlSelectTest.cs │ │ └── MySqlUpdateTest.cs │ ├── MySqlAdo │ │ └── MySqlAdoTest.cs │ ├── MySqlCodeFirstTest.cs │ ├── MySqlDbFirstTest.cs │ └── MySqlExpression │ │ ├── ConvertTest.cs │ │ ├── DateTimeTest.cs │ │ ├── MathTest.cs │ │ ├── OtherTest.cs │ │ ├── StringTest.cs │ │ └── TimeSpanTest.cs ├── Oracle │ ├── Curd │ │ ├── OracleDeleteTest.cs │ │ ├── OracleInsertTest.cs │ │ ├── OracleSelectTest.cs │ │ └── OracleUpdateTest.cs │ ├── OracleAdo │ │ └── OracleAdoTest.cs │ ├── OracleCodeFirstTest.cs │ └── OracleExpression │ │ ├── ConvertTest.cs │ │ ├── DateTimeTest.cs │ │ ├── MathTest.cs │ │ ├── OtherTest.cs │ │ ├── StringTest.cs │ │ └── TimeSpanTest.cs ├── PostgreSQL │ ├── Curd │ │ ├── PostgreSQLDeleteTest.cs │ │ ├── PostgreSQLInsertTest.cs │ │ ├── PostgreSQLSelectTest.cs │ │ └── PostgreSQLUpdateTest.cs │ ├── PostgreSQLAdo │ │ └── PostgreSQLAdoTest.cs │ ├── PostgreSQLCodeFirstTest.cs │ ├── PostgreSQLDbFirstTest.cs │ └── PostgreSQLExpression │ │ ├── ConvertTest.cs │ │ ├── DateTimeTest.cs │ │ ├── MathTest.cs │ │ ├── OtherTest.cs │ │ ├── StringTest.cs │ │ └── TimeSpanTest.cs ├── SqlServer │ ├── Curd │ │ ├── SqlServerDeleteTest.cs │ │ ├── SqlServerInsertTest.cs │ │ ├── SqlServerSelectTest.cs │ │ └── SqlServerUpdateTest.cs │ ├── SqlServerAdo │ │ └── SqlServerAdoTest.cs │ ├── SqlServerCodeFirstTest.cs │ ├── SqlServerDbFirstTest.cs │ └── SqlServerExpression │ │ ├── ConvertTest.cs │ │ ├── DateTimeTest.cs │ │ ├── MathTest.cs │ │ ├── OtherTest.cs │ │ ├── StringTest.cs │ │ └── TimeSpanTest.cs ├── Sqlite │ ├── Curd │ │ ├── SqliteDeleteTest.cs │ │ ├── SqliteInsertTest.cs │ │ ├── SqliteSelectTest.cs │ │ └── SqliteUpdateTest.cs │ ├── SqliteAdo │ │ └── SqliteAdoTest.cs │ ├── SqliteCodeFirstTest.cs │ └── SqliteExpression │ │ ├── ConvertTest.cs │ │ ├── DateTimeTest.cs │ │ ├── MathTest.cs │ │ ├── OtherTest.cs │ │ ├── StringTest.cs │ │ └── TimeSpanTest.cs ├── UnitTest1.cs └── g.cs ├── FreeSql.sln ├── FreeSql ├── DataAnnotations │ ├── ColumnAttribute.cs │ ├── ColumnFluent.cs │ ├── TableAttribute.cs │ └── TableFluent.cs ├── DatabaseModel │ ├── DBColumnInfo.cs │ ├── DBTableInfo.cs │ ├── DbEnumInfo.cs │ ├── DbForeignInfo.cs │ └── DbTypeInfo.cs ├── Extensions │ ├── FreeSqlGlobalExtensions.cs │ └── FreeSqlStringExtensions.cs ├── FreeSql.csproj ├── FreeSqlBuilder.cs ├── FreeUtil.cs ├── Generator │ ├── TemplateEngin.cs │ └── TemplateGenerator.cs ├── Interface │ ├── Curd │ │ ├── IDelete.cs │ │ ├── IInsert.cs │ │ ├── ISelect │ │ │ ├── ISelect0.cs │ │ │ ├── ISelect1.cs │ │ │ ├── ISelect10.cs │ │ │ ├── ISelect3.cs │ │ │ ├── ISelect4.cs │ │ │ ├── ISelect5.cs │ │ │ ├── ISelect6.cs │ │ │ ├── ISelect7.cs │ │ │ ├── ISelect8.cs │ │ │ ├── ISelect9.cs │ │ │ ├── ISelectFrom.cs │ │ │ └── ISelectGrouping.cs │ │ └── IUpdate.cs │ ├── IAdo.cs │ ├── IAop.cs │ ├── ICache.cs │ ├── ICodeFirst.cs │ ├── IFreeSql.cs │ └── iDbFirst.cs ├── Internal │ ├── CommonExpression.cs │ ├── CommonProvider │ │ ├── AdoProvider │ │ │ ├── AdoProvider.cs │ │ │ ├── AdoProviderAsync.cs │ │ │ ├── AdoProviderTransaction.cs │ │ │ └── AdoProviderUtils.cs │ │ ├── CacheProvider.cs │ │ ├── DeleteProvider.cs │ │ ├── InsertProvider.cs │ │ ├── SelectProvider │ │ │ ├── Select0Provider.cs │ │ │ ├── Select10Provider.cs │ │ │ ├── Select1Provider.cs │ │ │ ├── Select3Provider.cs │ │ │ ├── Select4Provider.cs │ │ │ ├── Select5Provider.cs │ │ │ ├── Select6Provider.cs │ │ │ ├── Select7Provider.cs │ │ │ ├── Select8Provider.cs │ │ │ ├── Select9Provider.cs │ │ │ └── SelectGroupingProvider.cs │ │ └── UpdateProvider.cs │ ├── CommonUtils.cs │ ├── Model │ │ ├── ColumnInfo.cs │ │ ├── ReadAnonymousTypeInfo.cs │ │ ├── SelectColumnInfo.cs │ │ ├── SelectTableInfo.cs │ │ └── TableInfo.cs │ ├── UtilsExpressionTree.cs │ └── UtilsReflection.cs ├── MySql │ ├── Curd │ │ ├── MySqlDelete.cs │ │ ├── MySqlInsert.cs │ │ ├── MySqlSelect.cs │ │ └── MySqlUpdate.cs │ ├── MySqlAdo │ │ ├── MySqlAdo.cs │ │ ├── MySqlConnectionPool.cs │ │ ├── MygisTypes.cs │ │ └── MygisTypesExtensions.cs │ ├── MySqlCodeFirst.cs │ ├── MySqlDbFirst.cs │ ├── MySqlExpression.cs │ ├── MySqlProvider.cs │ └── MySqlUtils.cs ├── Oracle │ ├── Curd │ │ ├── OracleDelete.cs │ │ ├── OracleInsert.cs │ │ ├── OracleSelect.cs │ │ └── OracleUpdate.cs │ ├── OracleAdo │ │ ├── OracleAdo.cs │ │ └── OracleConnectionPool.cs │ ├── OracleCodeFirst.cs │ ├── OracleExpression.cs │ ├── OracleProvider.cs │ └── OracleUtils.cs ├── PostgreSQL │ ├── Curd │ │ ├── PostgreSQLDelete.cs │ │ ├── PostgreSQLInsert.cs │ │ ├── PostgreSQLSelect.cs │ │ └── PostgreSQLUpdate.cs │ ├── PostgreSQLAdo │ │ ├── PostgreSQLAdo.cs │ │ ├── PostgreSQLConnectionPool.cs │ │ ├── PostgreSQLTypesConverter.cs │ │ └── PostgreSQLTypesExtensions.cs │ ├── PostgreSQLCodeFirst.cs │ ├── PostgreSQLDbFirst.cs │ ├── PostgreSQLExpression.cs │ ├── PostgreSQLProvider.cs │ └── PostgreSQLUtils.cs ├── SqlServer │ ├── Curd │ │ ├── SqlServerDelete.cs │ │ ├── SqlServerInsert.cs │ │ ├── SqlServerSelect.cs │ │ └── SqlServerUpdate.cs │ ├── SqlServerAdo │ │ ├── SqlServerAdo.cs │ │ └── SqlServerConnectionPool.cs │ ├── SqlServerCodeFirst.cs │ ├── SqlServerDbFirst.cs │ ├── SqlServerExpression.cs │ ├── SqlServerProvider.cs │ └── SqlServerUtils.cs └── Sqlite │ ├── Curd │ ├── SqliteDelete.cs │ ├── SqliteInsert.cs │ ├── SqliteSelect.cs │ └── SqliteUpdate.cs │ ├── SqliteAdo │ ├── SqliteAdo.cs │ └── SqliteConnectionPool.cs │ ├── SqliteCodeFirst.cs │ ├── SqliteExpression.cs │ ├── SqliteProvider.cs │ └── SqliteUtils.cs ├── LICENSE ├── Templates ├── MySql │ ├── include │ │ └── enumtype.tpl │ ├── rich-entity-navigation-object │ │ ├── Const.cs │ │ ├── Model │ │ │ └── for-table.cs.freesql │ │ └── readme.md │ ├── simple-entity-navigation-object │ │ ├── Model │ │ │ └── for-table.cs.freesql │ │ └── readme.md │ └── simple-entity │ │ ├── Model │ │ └── for-table.cs.freesql │ │ └── readme.md ├── PostgreSQL │ ├── rich-entity-navigation-object │ │ ├── Const.cs │ │ ├── Model │ │ │ └── for-table.cs.freesql │ │ └── readme.md │ ├── simple-entity-navigation-object │ │ ├── Model │ │ │ └── for-table.cs.freesql │ │ └── readme.md │ └── simple-entity │ │ ├── Model │ │ └── for-table.cs.freesql │ │ └── readme.md └── SqlServer │ ├── rich-entity-navigation-object │ ├── Const.cs │ ├── Model │ │ └── for-table.cs.freesql │ └── readme.md │ ├── simple-entity-navigation-object │ ├── Model │ │ └── for-table.cs.freesql │ └── readme.md │ └── simple-entity │ ├── Model │ └── for-table.cs.freesql │ └── readme.md └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain -------------------------------------------------------------------------------- /Docs/1. quickstart.md: -------------------------------------------------------------------------------- 1 | # FreeSql 简介 2 | 3 | FreeSql 是轻量化、可扩展和跨平台版的 .NETStandard 数据访问技术实现。 4 | 5 | FreeSql 可用作对象关系映射程序 (O/RM),以便于开发人员能够使用 .NETStandard 对象来处理数据库,不必经常编写大部分数据访问代码。 6 | 7 | FreeSql 支持 MySql/SqlServer/PostgreSQL 数据库技术实现。 8 | 9 | ## 模型 10 | 11 | FreeSql 使用模型执行数据访问,模型由实体类表示数据库表或视图,用于查询和保存数据。 有关详细信息,请参阅创建模型。 12 | 13 | 可从现有数据库生成实体模型,提供 IDbFirst 生成实体模型。 14 | 15 | 或者手动创建模型,基于模型创建或修改数据库,提供 ICodeFirst 同步结构的 API(甚至可以做到开发阶段自动同步)。 16 | 17 | ```csharp 18 | using FreeSql.DataAnnotations; 19 | using System; 20 | 21 | public class Blog 22 | { 23 | [Column(IsIdentity = true, IsPrimary = true)] 24 | public int BlogId { get; set; } 25 | public string Url { get; set; } 26 | public int Rating { get; set; } 27 | } 28 | 29 | public class Post 30 | { 31 | public int PostId { get; set; } 32 | public string Title { get; set; } 33 | public string Content { get; set; } 34 | 35 | public int BlogId { get; set; } 36 | public Blog Blog { get; set; } 37 | } 38 | ``` 39 | 40 | ## 声明 41 | 42 | ```csharp 43 | var connstr = "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;" + 44 | "Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10"; 45 | 46 | IFreeSql fsql = new FreeSql.FreeSqlBuilder() 47 | .UseConnectionString(FreeSql.DataType.MySql, connstr) 48 | .UseSlave("connectionString1", "connectionString2") //使用从数据库,支持多个 49 | 50 | .UseLogger(null) //使用日志,不指定默认输出控制台 ILogger 51 | .UseCache(null) //使用缓存,不指定默认使用内存 IDistributedCache 52 | 53 | .UseAutoSyncStructure(true) //自动同步实体结构到数据库 54 | .UseSyncStructureToLower(true) //转小写同步结构 55 | .Build(); 56 | ``` 57 | 58 | 注意: IFreeSql 在项目中应以单例声明,而不是在每次使用的时候创建。 59 | 60 | ## 查询 61 | 62 | ```csharp 63 | var blogs = fsql.Select 64 | .Where(b => b.Rating > 3) 65 | .OrderBy(b => b.Url) 66 | .ToList(); 67 | ``` 68 | 69 | ## 插入 70 | 71 | ```csharp 72 | var blog = new Blog { Url = "http://sample.com" }; 73 | blog.BlogId = (int)fsql.Insert() 74 | .AppendData(blog) 75 | .ExecuteIdentity(); 76 | ``` 77 | 78 | ## 更新 79 | 80 | ```csharp 81 | fsql.Update() 82 | .Set(b => b.Url, "http://sample2222.com") 83 | .Where(b => b.Url == "http://sample.com") 84 | .ExecuteAffrows(); 85 | ``` 86 | 87 | ## 删除 88 | 89 | ```csharp 90 | fsql.Delete() 91 | .Where(b => b.Url == "http://sample.com") 92 | .ExecuteAffrows(); 93 | ``` 94 | 95 | ## 后续步骤 96 | 97 | 有关介绍性教程,请参阅 [FreeSql 入门]()。 98 | -------------------------------------------------------------------------------- /Docs/2 入门.md: -------------------------------------------------------------------------------- 1 | # FreeSql 入门 2 | 3 | ## 安装 4 | 5 | FreeSql 是一个 .NET Standard 2.0 库,支持 .NET Framework 4.6.1 或 .NET Core 或更高版本的应用程序。 6 | 7 | ```shell 8 | dotnet add package FreeSql 9 | ``` 10 | 11 | 或者 12 | 13 | ```shell 14 | Install-Package FreeSql 15 | ``` 16 | 17 | ## 入门教程 18 | 19 | FreeSql 可基于现有数据库创建模型,也可基于模型创建数据库。 提供的教程演示了这两种方法。 20 | 21 | * .NET Core 控制台应用 22 | 23 | - * 新建数据库 24 | 25 | * ASP.NET Core 应用 26 | 27 | - * 新建数据库 28 | - * 现有数据库 -------------------------------------------------------------------------------- /Docs/2.1 安装FreeSql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YSGStudyHards/FreeSql/7e59e079567c84606ca0b74bcddd6d2d24d841fa/Docs/2.1 安装FreeSql -------------------------------------------------------------------------------- /Docs/dbfirst.md: -------------------------------------------------------------------------------- 1 | # DbFirst 2 | 3 | ```csharp 4 | IFreeSql fsql = new FreeSql.FreeSqlBuilder() 5 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 6 | .Build(); 7 | ``` 8 | 9 | ### 获取所有数据库 10 | 11 | ```csharp 12 | var t1 = fsql.DbFirst.GetDatabases(); 13 | //返回字符串数组, ["cccddd", "test"] 14 | ``` 15 | 16 | ### 获取指定数据库的表信息 17 | 18 | ```csharp 19 | var t2 = fsql.DbFirst.GetTablesByDatabase(fsql.DbFirst.GetDatabases()[0]); 20 | //返回包括表、列详情、主键、唯一键、索引、外键 21 | ``` 22 | 23 | # 生成器 24 | 25 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 26 | 27 | | 模板名称 | 路径 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 28 | | ------------- | - | - |- | - |- | - |- | 29 | | simple-entity | ../Templates/MySql/simple-entity | √ | X | X | √ | X | X | 30 | | simple-entity-navigation-object | ../Templates/MySql/simple-entity-navigation-object | √ | √ | X | √ | X | X | 31 | | rich-entity-navigation-object | ../Templates/MySql/rich-entity-navigation-object | √ | √ | √ | X | √ | X | 32 | 33 | > 更多模板逐步开发中。。。 34 | 35 | ```csharp 36 | //创建模板生成类现实 37 | var gen = new FreeSql.Generator.TemplateGenerator(); 38 | gen.Build(fsql.DbFirst, 39 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 40 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 41 | "cccddd" //数据库 42 | ); 43 | ``` 44 | 45 | ## 模板语法 46 | 47 | ```html 48 | 49 | 50 | {#title} 51 | 52 | 53 | 54 | 55 | {#表达式} 56 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 57 | 58 | 59 | {include ../header.html} 60 |
61 |

aaa

62 |

bbb {#i}

63 |

ccc {#i}

64 |
65 | 66 | 67 | {module module_name1 parms1, 2, 3...} 68 | {/module} 69 | {module module_name2 parms1, 2, 3...} 70 | {/module} 71 | 72 | 73 | {import ../module.html as myname} 74 | {#myname.module_name(parms1, 2, 3...)} 75 | 76 | 77 | {extends ../inc/layout.html} 78 | {block body}{/block} 79 | 80 | 81 | {% 82 | for (var a = 0; a < 100; a++) 83 | print(a); 84 | %} 85 | 86 | 87 | {if i === 50} 88 | {elseif i > 60} 89 | {else} 90 | {/if} 91 | 92 | 93 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 94 | 95 | {for item,index in items} 可选参数称 index 96 | 可自定义名 {for item2, index99 in 数组表达式} 97 | 98 | {for key,item,index on json} 可选参数 item, index, 99 | 可自定义名 {for key2, item2, index99 in 对象表达式} 100 | {/for} 101 | 102 | 103 | {miss} 104 | 此块内容不被bmw.js解析 105 | {/miss} 106 | 107 | 108 | 109 | ``` -------------------------------------------------------------------------------- /Docs/delete.md: -------------------------------------------------------------------------------- 1 | # 删除数据 2 | 3 | | 方法 | 返回值 | 参数 | 描述 | 4 | | - | - | - | - | 5 | | Where | \ | Lambda | 表达式条件,仅支持实体基础成员(不包含导航对象) | 6 | | Where | \ | string, parms | 原生sql语法条件,Where("id = ?id", new { id = 1 }) | 7 | | Where | \ | T1 \| IEnumerable | 传入实体或集合,将其主键作为条件 | 8 | | WhereExists | \ | ISelect | 子查询是否存在 | 9 | | ToSql | string | | 返回即将执行的SQL语句 | 10 | | ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | 11 | | ExecuteDeleted | List\ | | 执行SQL语句,返回被删除的记录 | 12 | 13 | ### 测试代码 14 | 15 | ```csharp 16 | IFreeSql fsql = new FreeSql.FreeSqlBuilder() 17 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 18 | .Build(); 19 | IDelete delete => fsql.Delete(); 20 | 21 | [Table(Name = "tb_topic")] 22 | class Topic { 23 | [Column(IsIdentity = true, IsPrimary = true)] 24 | public int Id { get; set; } 25 | public int Clicks { get; set; } 26 | public TestTypeInfo Type { get; set; } 27 | public string Title { get; set; } 28 | public DateTime CreateTime { get; set; } 29 | } 30 | ``` 31 | 32 | ### 动态条件 33 | ```csharp 34 | Delete(object dywhere) 35 | ``` 36 | dywhere 支持 37 | 38 | * 主键值 39 | * new[] { 主键值1, 主键值2 } 40 | * Topic对象 41 | * new[] { Topic对象1, Topic对象2 } 42 | * new { id = 1 } 43 | 44 | ```csharp 45 | var t1 = fsql.Delete(new[] { 1, 2 }).ToSql(); 46 | //DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2) 47 | 48 | var t2 = fsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); 49 | //DELETE FROM `tb_topic` WHERE (`Id` = 1) 50 | 51 | var t3 = fsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); 52 | //DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2) 53 | 54 | var t4 = fsql.Delete(new { id = 1 }).ToSql(); 55 | //DELETE FROM `tb_topic` WHERE (`Id` = 1) 56 | ``` 57 | 58 | ### 删除条件 59 | 60 | ```csharp 61 | var t5 = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); 62 | //DELETE FROM `tb_topic` WHERE (`Id` = 1) 63 | 64 | var t6 = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); 65 | //DELETE FROM `tb_topic` WHERE (id = ?id) 66 | 67 | var item = new Topic { Id = 1, Title = "newtitle" }; 68 | var t7 = delete.Where(item).ToSql().Replace("\r\n", ""); 69 | //DELETE FROM `tb_topic` WHERE (`Id` = 1) 70 | 71 | var items = new List(); 72 | for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); 73 | var t8 = delete.Where(items).ToSql().Replace("\r\n", ""); 74 | //DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10)) 75 | ``` 76 | 77 | ### 执行命令 78 | 79 | | 方法 | 返回值 | 参数 | 描述 | 80 | | - | - | - | - | 81 | | ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | 82 | | ExecuteDeleted | List\ | | 执行SQL语句,返回被删除的记录 | -------------------------------------------------------------------------------- /Docs/generator.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | IFreeSql fsql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .UseAutoSyncStructure(true) 20 | 21 | .UseMonitorCommand( 22 | cmd => { 23 | Console.WriteLine(cmd.CommandText); 24 | }, //监听SQL命令对象,在执行前 25 | (cmd, traceLog) => { 26 | Console.WriteLine(traceLog); 27 | }) //监听SQL命令对象,在执行后 28 | .Build(); 29 | 30 | //创建模板生成类现实 31 | var gen = new FreeSql.Generator.TemplateGenerator(); 32 | gen.Build(mysql.DbFirst, 33 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 34 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 35 | "cccddd" //数据库 36 | ); 37 | ``` 38 | 39 | ## 模板语法 40 | 41 | ```html 42 | 43 | 44 | {#title} 45 | 46 | 47 | 48 | 49 | {#表达式} 50 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 51 | 52 | 53 | {include ../header.html} 54 |
55 |

aaa

56 |

bbb {#i}

57 |

ccc {#i}

58 |
59 | 60 | 61 | {module module_name1 parms1, 2, 3...} 62 | {/module} 63 | {module module_name2 parms1, 2, 3...} 64 | {/module} 65 | 66 | 67 | {import ../module.html as myname} 68 | {#myname.module_name(parms1, 2, 3...)} 69 | 70 | 71 | {extends ../inc/layout.html} 72 | {block body}{/block} 73 | 74 | 75 | {% 76 | for (var a = 0; a < 100; a++) 77 | print(a); 78 | %} 79 | 80 | 81 | {if i === 50} 82 | {elseif i > 60} 83 | {else} 84 | {/if} 85 | 86 | 87 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 88 | 89 | {for item,index in items} 可选参数称 index 90 | 可自定义名 {for item2, index99 in 数组表达式} 91 | 92 | {for key,item,index on json} 可选参数 item, index, 93 | 可自定义名 {for key2, item2, index99 in 对象表达式} 94 | {/for} 95 | 96 | 97 | {miss} 98 | 此块内容不被bmw.js解析 99 | {/miss} 100 | 101 | 102 | 103 | ``` -------------------------------------------------------------------------------- /Docs/insert.md: -------------------------------------------------------------------------------- 1 | # 插入数据 2 | 3 | | 方法 | 返回值 | 参数 | 描述 | 4 | | - | - | - | - | 5 | | AppendData | \ | T1 \| IEnumerable | 追加准备插入的实体 | 6 | | InsertColumns | \ | Lambda | 只插入的列 | 7 | | IgnoreColumns | \ | Lambda | 忽略的列 | 8 | | ToSql | string | | 返回即将执行的SQL语句 | 9 | | ExecuteAffrows | long | | 执行SQL语句,返回影响的行数 | 10 | | ExecuteIdentity | long | | 执行SQL语句,返回自增值 | 11 | | ExecuteInserted | List\ | | 执行SQL语句,返回插入后的记录 | 12 | 13 | ### 列优先级 14 | 15 | > 全部列 < 指定列(InsertColumns) < 忽略列(IgnoreColumns) 16 | 17 | ### 测试代码 18 | 19 | ```csharp 20 | IFreeSql fsql = new FreeSql.FreeSqlBuilder() 21 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 22 | .Build(); 23 | IInsert insert => fsql.Insert(); 24 | 25 | [Table(Name = "tb_topic")] 26 | class Topic { 27 | [Column(IsIdentity = true, IsPrimary = true)] 28 | public int Id { get; set; } 29 | public int Clicks { get; set; } 30 | public TestTypeInfo Type { get; set; } 31 | public string Title { get; set; } 32 | public DateTime CreateTime { get; set; } 33 | } 34 | 35 | var items = new List(); 36 | for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); 37 | ``` 38 | 39 | ### 插入 40 | 41 | ```csharp 42 | var t1 = insert.AppendData(items.First()).ToSql(); 43 | //INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks0, ?Title0, ?CreateTime0) 44 | ``` 45 | 46 | ### 批量插入 47 | 48 | ```csharp 49 | var t2 = insert.AppendData(items).ToSql(); 50 | //INSERT INTO `tb_topic`(`Clicks`, `Title`, `CreateTime`) VALUES(?Clicks0, ?Title0, ?CreateTime0), (?Clicks1, ?Title1, ?CreateTime1), (?Clicks2, ?Title2, ?CreateTime2), (?Clicks3, ?Title3, ?CreateTime3), (?Clicks4, ?Title4, ?CreateTime4), (?Clicks5, ?Title5, ?CreateTime5), (?Clicks6, ?Title6, ?CreateTime6), (?Clicks7, ?Title7, ?CreateTime7), (?Clicks8, ?Title8, ?CreateTime8), (?Clicks9, ?Title9, ?CreateTime9) 51 | ``` 52 | 53 | ### 只想插入指定的列 54 | 55 | ```csharp 56 | var t3 = insert.AppendData(items).InsertColumns(a => a.Title).ToSql(); 57 | //INSERT INTO `tb_topic`(`Title`) VALUES(?Title0), (?Title1), (?Title2), (?Title3), (?Title4), (?Title5), (?Title6), (?Title7), (?Title8), (?Title9) 58 | 59 | var t4 = insert.AppendData(items).InsertColumns(a =>new { a.Title, a.Clicks }).ToSql(); 60 | //INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9) 61 | ``` 62 | 63 | ### 忽略列 64 | 65 | ```csharp 66 | var t5 = insert.AppendData(items).IgnoreColumns(a => a.CreateTime).ToSql(); 67 | //INSERT INTO `tb_topic`(`Clicks`, `Title`) VALUES(?Clicks0, ?Title0), (?Clicks1, ?Title1), (?Clicks2, ?Title2), (?Clicks3, ?Title3), (?Clicks4, ?Title4), (?Clicks5, ?Title5), (?Clicks6, ?Title6), (?Clicks7, ?Title7), (?Clicks8, ?Title8), (?Clicks9, ?Title9) 68 | 69 | var t6 = insert.AppendData(items).IgnoreColumns(a => new { a.Title, a.CreateTime }).ToSql(); 70 | ///INSERT INTO `tb_topic`(`Clicks`) VALUES(?Clicks0), (?Clicks1), (?Clicks2), (?Clicks3), (?Clicks4), (?Clicks5), (?Clicks6), (?Clicks7), (?Clicks8), (?Clicks9) 71 | ``` 72 | 73 | ### 执行命令 74 | 75 | | 方法 | 返回值 | 描述 | 76 | | - | - | - | 77 | | ExecuteAffrows | long | 执行SQL语句,返回影响的行数 | 78 | | ExecuteIdentity | long | 执行SQL语句,返回自增值 | 79 | | ExecuteInserted | List\ | 执行SQL语句,返回插入后的记录 | 80 | -------------------------------------------------------------------------------- /FreeSql.Tests.PerformanceTests/FreeSql.Tests.PerformanceTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /FreeSql.Tests.PerformanceTests/g.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Logging; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | 7 | public class g { 8 | 9 | public static IFreeSql mysql = new FreeSql.FreeSqlBuilder() 10 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=100") 11 | .UseLogger(new LoggerFactory().CreateLogger("FreeSql.MySql")) 12 | .UseAutoSyncStructure(false) 13 | .Build(); 14 | 15 | //public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() 16 | // .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=10") 17 | // .UseLogger(new LoggerFactory().CreateLogger("FreeSql.SqlServer")) 18 | // .UseAutoSyncStructure(false) 19 | // .Build(); 20 | 21 | //public static IFreeSql pgsql = new FreeSql.FreeSqlBuilder() 22 | // .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") 23 | // .UseLogger(new LoggerFactory().CreateLogger("FreeSql.PostgreSQL")) 24 | // .UseAutoSyncStructure(false) 25 | // .UseSyncStructureToLower(true) 26 | // .Build(); 27 | 28 | //public static IFreeSql oracle = new FreeSql.FreeSqlBuilder() 29 | // .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") 30 | // .UseLogger(new LoggerFactory().CreateLogger("FreeSql.Oracle")) 31 | // .UseAutoSyncStructure(false) 32 | // .Build(); 33 | 34 | //public static IFreeSql sqlite = new FreeSql.FreeSqlBuilder() 35 | // .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") 36 | // .UseLogger(new LoggerFactory().CreateLogger("FreeSql.Sqlite")) 37 | // .UseAutoSyncStructure(false) 38 | // .Build(); 39 | } 40 | -------------------------------------------------------------------------------- /FreeSql.Tests/Class1.cs: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /FreeSql.Tests/DataAnnotations/FluentTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using Xunit; 3 | 4 | namespace FreeSql.Tests.DataAnnotations { 5 | public class FluentTest { 6 | [Fact] 7 | public void Fluent() { 8 | g.mysql.CodeFirst 9 | .ConfigEntity(a => { 10 | a.Name("xxdkdkdk1").SelectFilter("a.Id22 > 0"); 11 | a.Property(b => b.Id).Name("Id22").IsIdentity(true); 12 | a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); 13 | }) 14 | .ConfigEntity(a => { 15 | a.Name("xxdkdkdk2").SelectFilter("a.Idx > 0"); 16 | a.Property(b => b.Id).Name("Id22").IsIdentity(true); 17 | a.Property(b => b.name).DbType("varchar(100)").IsNullable(true); 18 | }); 19 | 20 | var ddl1 = g.mysql.CodeFirst.GetComparisonDDLStatements(); 21 | var ddl2 = g.mysql.CodeFirst.GetComparisonDDLStatements(); 22 | 23 | var t1id = g.mysql.Insert().AppendData(new TestFluenttb1 { }).ExecuteIdentity(); 24 | var t1 = g.mysql.Select(t1id).ToOne(); 25 | 26 | var t2lastId = g.mysql.Select().Max(a => a.Id); 27 | var t2affrows = g.mysql.Insert().AppendData(new TestFluenttb2 { Id = t2lastId + 1 }).ExecuteAffrows(); 28 | var t2 = g.mysql.Select(t2lastId + 1).ToOne(); 29 | } 30 | } 31 | 32 | class TestFluenttb1 { 33 | public int Id { get; set; } 34 | 35 | public string name { get; set; } = "defaultValue"; 36 | } 37 | 38 | [Table(Name = "cccccdddwww")] 39 | class TestFluenttb2 { 40 | [Column(Name = "Idx", IsPrimary = true, IsIdentity = false)] 41 | public int Id { get; set; } 42 | 43 | public string name { get; set; } = "defaultValue"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /FreeSql.Tests/FreeSql.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.1 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /FreeSql.Tests/Generator/MySqlTemplateGeneratorTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using FreeSql.Generator; 3 | using System; 4 | using Xunit; 5 | 6 | namespace FreeSql.Tests.Generator { 7 | public class MySqlTemplateGeneratorTest { 8 | 9 | [Fact] 10 | public void BuildSimpleEntity() { 11 | var gen = new TemplateGenerator(); 12 | gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd"); 13 | } 14 | 15 | [Fact] 16 | public void BuildSimpleEntityNavigationObject () { 17 | var gen = new TemplateGenerator(); 18 | gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd"); 19 | } 20 | 21 | [Fact] 22 | public void BuildRichEntityNavigationObject() { 23 | var gen = new TemplateGenerator(); 24 | gen.Build(g.mysql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "cccddd"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /FreeSql.Tests/Generator/PostgreSQLTemplateGeneratorTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using FreeSql.Generator; 3 | using System; 4 | using Xunit; 5 | 6 | namespace FreeSql.Tests.Generator { 7 | public class PostgreSQLTemplateGeneratorTest { 8 | 9 | [Fact] 10 | public void BuildSimpleEntity() { 11 | var gen = new TemplateGenerator(); 12 | gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb"); 13 | } 14 | 15 | [Fact] 16 | public void BuildSimpleEntityNavigationObject () { 17 | var gen = new TemplateGenerator(); 18 | gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb"); 19 | } 20 | 21 | [Fact] 22 | public void BuildRichEntityNavigationObject() { 23 | var gen = new TemplateGenerator(); 24 | gen.Build(g.pgsql.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\PostgreSQL\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "tedb"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /FreeSql.Tests/Generator/SqlServerTemplateGeneratorTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using FreeSql.Generator; 3 | using System; 4 | using Xunit; 5 | 6 | namespace FreeSql.Tests.Generator { 7 | public class SqlServerTemplateGeneratorTest { 8 | 9 | [Fact] 10 | public void BuildSimpleEntity() { 11 | var gen = new TemplateGenerator(); 12 | gen.Build(g.sqlserver.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\simple-entity", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop"); 13 | } 14 | 15 | [Fact] 16 | public void BuildSimpleEntityNavigationObject () { 17 | var gen = new TemplateGenerator(); 18 | gen.Build(g.sqlserver.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\simple-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop"); 19 | } 20 | 21 | [Fact] 22 | public void BuildRichEntityNavigationObject() { 23 | var gen = new TemplateGenerator(); 24 | gen.Build(g.sqlserver.DbFirst, @"C:\Users\28810\Desktop\github\FreeSql\Templates\SqlServer\rich-entity-navigation-object", @"C:\Users\28810\Desktop\新建文件夹 (9)", "shop"); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /FreeSql.Tests/MySql/Curd/MySqlDeleteTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Xunit; 6 | 7 | namespace FreeSql.Tests.MySql { 8 | public class MySqlDeleteTest { 9 | 10 | IDelete delete => g.mysql.Delete(); //�������� 11 | 12 | [Table(Name = "tb_topic")] 13 | class Topic { 14 | [Column(IsIdentity = true, IsPrimary = true)] 15 | public int Id { get; set; } 16 | public int Clicks { get; set; } 17 | public TestTypeInfo Type { get; set; } 18 | public string Title { get; set; } 19 | public DateTime CreateTime { get; set; } 20 | } 21 | 22 | [Fact] 23 | public void Dywhere() { 24 | Assert.Null(g.mysql.Delete().ToSql()); 25 | var sql = g.mysql.Delete(new[] { 1, 2 }).ToSql(); 26 | Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); 27 | 28 | sql = g.mysql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); 29 | Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); 30 | 31 | sql = g.mysql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); 32 | Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1 OR `Id` = 2)", sql); 33 | 34 | sql = g.mysql.Delete(new { id = 1 }).ToSql(); 35 | Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); 36 | } 37 | 38 | [Fact] 39 | public void Where() { 40 | var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); 41 | Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); 42 | 43 | sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); 44 | Assert.Equal("DELETE FROM `tb_topic` WHERE (id = ?id)", sql); 45 | 46 | var item = new Topic { Id = 1, Title = "newtitle" }; 47 | sql = delete.Where(item).ToSql().Replace("\r\n", ""); 48 | Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` = 1)", sql); 49 | 50 | var items = new List(); 51 | for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); 52 | 53 | sql = delete.Where(items).ToSql().Replace("\r\n", ""); 54 | Assert.Equal("DELETE FROM `tb_topic` WHERE (`Id` IN (1,2,3,4,5,6,7,8,9,10))", sql); 55 | } 56 | [Fact] 57 | public void WhereExists() { 58 | 59 | } 60 | [Fact] 61 | public void ExecuteAffrows() { 62 | 63 | var id = g.mysql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); 64 | Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); 65 | } 66 | [Fact] 67 | public void ExecuteDeleted() { 68 | 69 | //delete.Where(a => a.Id > 0).ExecuteDeleted(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /FreeSql.Tests/MySql/MySqlAdo/MySqlAdoTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.MySql { 6 | public class MySqlAdoTest { 7 | [Fact] 8 | public void Pool() { 9 | var t1 = g.mysql.Ado.MasterPool.StatisticsFullily; 10 | } 11 | 12 | [Fact] 13 | public void SlavePools() { 14 | var t2 = g.mysql.Ado.SlavePools.Count; 15 | } 16 | 17 | [Fact] 18 | public void ExecuteReader() { 19 | 20 | } 21 | [Fact] 22 | public void ExecuteArray() { 23 | 24 | } 25 | [Fact] 26 | public void ExecuteNonQuery() { 27 | 28 | } 29 | [Fact] 30 | public void ExecuteScalar() { 31 | 32 | } 33 | 34 | [Fact] 35 | public void Query() { 36 | var t3 = g.mysql.Ado.Query("select * from song"); 37 | 38 | var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song"); 39 | 40 | var t5 = g.mysql.Ado.Query("select * from song"); 41 | } 42 | 43 | class xxx { 44 | public int Id { get; set; } 45 | public string Path { get; set; } 46 | public string Title2 { get; set; } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /FreeSql.Tests/MySql/MySqlCodeFirstTest.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YSGStudyHards/FreeSql/7e59e079567c84606ca0b74bcddd6d2d24d841fa/FreeSql.Tests/MySql/MySqlCodeFirstTest.cs -------------------------------------------------------------------------------- /FreeSql.Tests/MySql/MySqlDbFirstTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.MySql { 6 | public class MySqlDbFirstTest { 7 | [Fact] 8 | public void GetDatabases() { 9 | 10 | var t1 = g.mysql.DbFirst.GetDatabases(); 11 | 12 | } 13 | 14 | [Fact] 15 | public void GetTablesByDatabase() { 16 | 17 | var t2 = g.mysql.DbFirst.GetTablesByDatabase(g.mysql.DbFirst.GetDatabases()[0]); 18 | 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /FreeSql.Tests/Oracle/Curd/OracleDeleteTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Xunit; 6 | 7 | namespace FreeSql.Tests.Oracle { 8 | public class OracleDeleteTest { 9 | 10 | IDelete delete => g.oracle.Delete(); //�������� 11 | 12 | [Table(Name = "tb_topic22211")] 13 | class Topic { 14 | [Column(IsIdentity = true, IsPrimary = true)] 15 | public int Id { get; set; } 16 | public int? Clicks { get; set; } 17 | public TestTypeInfo Type { get; set; } 18 | public string Title { get; set; } 19 | public DateTime CreateTime { get; set; } 20 | } 21 | 22 | [Fact] 23 | public void Dywhere() { 24 | Assert.Null(g.oracle.Delete().ToSql()); 25 | var sql = g.oracle.Delete(new[] { 1, 2 }).ToSql(); 26 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); 27 | 28 | sql = g.oracle.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); 29 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 30 | 31 | sql = g.oracle.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); 32 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); 33 | 34 | sql = g.oracle.Delete(new { id = 1 }).ToSql(); 35 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 36 | } 37 | 38 | [Fact] 39 | public void Where() { 40 | var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); 41 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 42 | 43 | sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); 44 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (id = ?id)", sql); 45 | 46 | var item = new Topic { Id = 1, Title = "newtitle" }; 47 | sql = delete.Where(item).ToSql().Replace("\r\n", ""); 48 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 49 | 50 | var items = new List(); 51 | for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); 52 | 53 | sql = delete.Where(items).ToSql().Replace("\r\n", ""); 54 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); 55 | } 56 | [Fact] 57 | public void WhereExists() { 58 | 59 | } 60 | [Fact] 61 | public void ExecuteAffrows() { 62 | 63 | var id = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); 64 | Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); 65 | } 66 | [Fact] 67 | public void ExecuteDeleted() { 68 | 69 | //var item = g.oracle.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); 70 | //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /FreeSql.Tests/Oracle/OracleAdo/OracleAdoTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.Oracle { 6 | public class OracleAdoTest { 7 | [Fact] 8 | public void Pool() { 9 | var t1 = g.oracle.Ado.MasterPool.StatisticsFullily; 10 | } 11 | 12 | [Fact] 13 | public void SlavePools() { 14 | var t2 = g.oracle.Ado.SlavePools.Count; 15 | } 16 | 17 | [Fact] 18 | public void ExecuteReader() { 19 | 20 | } 21 | [Fact] 22 | public void ExecuteArray() { 23 | 24 | } 25 | [Fact] 26 | public void ExecuteNonQuery() { 27 | 28 | } 29 | [Fact] 30 | public void ExecuteScalar() { 31 | 32 | } 33 | 34 | [Fact] 35 | public void Query() { 36 | var t3 = g.oracle.Ado.Query("select * from \"song\""); 37 | 38 | var t4 = g.oracle.Ado.Query<(int, string, string)>("select * from \"song\""); 39 | 40 | var t5 = g.oracle.Ado.Query("select * from \"song\""); 41 | } 42 | 43 | class xxx { 44 | public int Id { get; set; } 45 | public string Path { get; set; } 46 | public string Title2 { get; set; } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /FreeSql.Tests/Oracle/OracleCodeFirstTest.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YSGStudyHards/FreeSql/7e59e079567c84606ca0b74bcddd6d2d24d841fa/FreeSql.Tests/Oracle/OracleCodeFirstTest.cs -------------------------------------------------------------------------------- /FreeSql.Tests/Oracle/OracleExpression/OtherTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Linq; 4 | using Xunit; 5 | 6 | namespace FreeSql.Tests.OracleExpression { 7 | public class OtherTest { 8 | 9 | ISelect select => g.oracle.Select(); 10 | 11 | public OtherTest() { 12 | } 13 | 14 | 15 | [Fact] 16 | public void Array() { 17 | //in not in 18 | var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); 19 | //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); 20 | var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); 21 | 22 | var inarray = new[] { 1, 2, 3 }; 23 | var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); 24 | //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); 25 | var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); 26 | } 27 | 28 | [Table(Name = "tb_alltype")] 29 | class TableAllType { 30 | [Column(IsIdentity = true, IsPrimary = true)] 31 | public int Id { get; set; } 32 | 33 | public string id2 { get; set; } = "id2=10"; 34 | 35 | public bool Bool { get; set; } 36 | public sbyte SByte { get; set; } 37 | public short Short { get; set; } 38 | public int Int { get; set; } 39 | public long Long { get; set; } 40 | public byte Byte { get; set; } 41 | public ushort UShort { get; set; } 42 | public uint UInt { get; set; } 43 | public ulong ULong { get; set; } 44 | public double Double { get; set; } 45 | public float Float { get; set; } 46 | public decimal Decimal { get; set; } 47 | public TimeSpan TimeSpan { get; set; } 48 | public DateTime DateTime { get; set; } 49 | public DateTime DateTimeOffSet { get; set; } 50 | public byte[] Bytes { get; set; } 51 | public string String { get; set; } 52 | public Guid Guid { get; set; } 53 | 54 | public bool? BoolNullable { get; set; } 55 | public sbyte? SByteNullable { get; set; } 56 | public short? ShortNullable { get; set; } 57 | public int? IntNullable { get; set; } 58 | public long? testFielLongNullable { get; set; } 59 | public byte? ByteNullable { get; set; } 60 | public ushort? UShortNullable { get; set; } 61 | public uint? UIntNullable { get; set; } 62 | public ulong? ULongNullable { get; set; } 63 | public double? DoubleNullable { get; set; } 64 | public float? FloatNullable { get; set; } 65 | public decimal? DecimalNullable { get; set; } 66 | public TimeSpan? TimeSpanNullable { get; set; } 67 | public DateTime? DateTimeNullable { get; set; } 68 | public DateTime? DateTimeOffSetNullable { get; set; } 69 | public Guid? GuidNullable { get; set; } 70 | 71 | public TableAllTypeEnumType1 Enum1 { get; set; } 72 | public TableAllTypeEnumType1? Enum1Nullable { get; set; } 73 | public TableAllTypeEnumType2 Enum2 { get; set; } 74 | public TableAllTypeEnumType2? Enum2Nullable { get; set; } 75 | } 76 | 77 | public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } 78 | [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /FreeSql.Tests/PostgreSQL/Curd/PostgreSQLDeleteTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Xunit; 6 | 7 | namespace FreeSql.Tests.PostgreSQL { 8 | public class PostgreSQLDeleteTest { 9 | 10 | IDelete delete => g.pgsql.Delete(); 11 | 12 | [Table(Name = "tb_topic_del")] 13 | class Topic { 14 | [Column(IsIdentity = true, IsPrimary = true)] 15 | public int Id { get; set; } 16 | public int Clicks { get; set; } 17 | public TestTypeInfo Type { get; set; } 18 | public string Title { get; set; } 19 | public DateTime CreateTime { get; set; } 20 | } 21 | 22 | [Fact] 23 | public void Dywhere() { 24 | Assert.Null(g.pgsql.Delete().ToSql()); 25 | var sql = g.pgsql.Delete(new[] { 1, 2 }).ToSql(); 26 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); 27 | 28 | sql = g.pgsql.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); 29 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); 30 | 31 | sql = g.pgsql.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); 32 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1 OR \"id\" = 2)", sql); 33 | 34 | sql = g.pgsql.Delete(new { id = 1 }).ToSql(); 35 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); 36 | } 37 | 38 | [Fact] 39 | public void Where() { 40 | var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); 41 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); 42 | 43 | sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); 44 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (id = ?id)", sql); 45 | 46 | var item = new Topic { Id = 1, Title = "newtitle" }; 47 | sql = delete.Where(item).ToSql().Replace("\r\n", ""); 48 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" = 1)", sql); 49 | 50 | var items = new List(); 51 | for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); 52 | 53 | sql = delete.Where(items).ToSql().Replace("\r\n", ""); 54 | Assert.Equal("DELETE FROM \"tb_topic_del\" WHERE (\"id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); 55 | } 56 | [Fact] 57 | public void WhereExists() { 58 | 59 | } 60 | [Fact] 61 | public void ExecuteAffrows() { 62 | 63 | var id = g.pgsql.Insert(new Topic { Title = "xxxx" }).ExecuteIdentity(); 64 | Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); 65 | } 66 | [Fact] 67 | public void ExecuteDeleted() { 68 | 69 | delete.Where(a => a.Id > 0).ExecuteDeleted(); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /FreeSql.Tests/PostgreSQL/PostgreSQLAdo/PostgreSQLAdoTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.PostgreSQL { 6 | public class PostgreSQLAdoTest { 7 | [Fact] 8 | public void Pool() { 9 | var t1 = g.pgsql.Ado.MasterPool.StatisticsFullily; 10 | } 11 | 12 | [Fact] 13 | public void SlavePools() { 14 | var t2 = g.pgsql.Ado.SlavePools.Count; 15 | } 16 | 17 | [Fact] 18 | public void ExecuteReader() { 19 | 20 | } 21 | [Fact] 22 | public void ExecuteArray() { 23 | 24 | } 25 | [Fact] 26 | public void ExecuteNonQuery() { 27 | 28 | } 29 | [Fact] 30 | public void ExecuteScalar() { 31 | 32 | } 33 | 34 | [Fact] 35 | public void Query() { 36 | var t3 = g.pgsql.Ado.Query("select * from song"); 37 | 38 | var t4 = g.pgsql.Ado.Query<(int, string, string)>("select * from song"); 39 | 40 | var t5 = g.pgsql.Ado.Query("select * from song"); 41 | } 42 | 43 | class xxx { 44 | public int Id { get; set; } 45 | public string Path { get; set; } 46 | public string Title2 { get; set; } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YSGStudyHards/FreeSql/7e59e079567c84606ca0b74bcddd6d2d24d841fa/FreeSql.Tests/PostgreSQL/PostgreSQLCodeFirstTest.cs -------------------------------------------------------------------------------- /FreeSql.Tests/PostgreSQL/PostgreSQLDbFirstTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.PostgreSQL { 6 | public class PostgreSQLDbFirstTest { 7 | [Fact] 8 | public void GetDatabases() { 9 | 10 | var t1 = g.pgsql.DbFirst.GetDatabases(); 11 | 12 | } 13 | 14 | [Fact] 15 | public void GetTablesByDatabase() { 16 | 17 | var t2 = g.pgsql.DbFirst.GetTablesByDatabase(g.pgsql.DbFirst.GetDatabases()[1]); 18 | 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /FreeSql.Tests/SqlServer/Curd/SqlServerDeleteTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Xunit; 6 | 7 | namespace FreeSql.Tests.SqlServer { 8 | public class SqlServerDeleteTest { 9 | 10 | IDelete delete => g.sqlserver.Delete(); //�������� 11 | 12 | [Table(Name = "tb_topic22211")] 13 | class Topic { 14 | [Column(IsIdentity = true, IsPrimary = true)] 15 | public int Id { get; set; } 16 | public int? Clicks { get; set; } 17 | public TestTypeInfo Type { get; set; } 18 | public string Title { get; set; } 19 | public DateTime CreateTime { get; set; } 20 | } 21 | 22 | [Fact] 23 | public void Dywhere() { 24 | Assert.Null(g.sqlserver.Delete().ToSql()); 25 | var sql = g.sqlserver.Delete(new[] { 1, 2 }).ToSql(); 26 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); 27 | 28 | sql = g.sqlserver.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); 29 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); 30 | 31 | sql = g.sqlserver.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); 32 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1 OR [Id] = 2)", sql); 33 | 34 | sql = g.sqlserver.Delete(new { id = 1 }).ToSql(); 35 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); 36 | } 37 | 38 | [Fact] 39 | public void Where() { 40 | var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); 41 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); 42 | 43 | sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); 44 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE (id = ?id)", sql); 45 | 46 | var item = new Topic { Id = 1, Title = "newtitle" }; 47 | sql = delete.Where(item).ToSql().Replace("\r\n", ""); 48 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] = 1)", sql); 49 | 50 | var items = new List(); 51 | for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); 52 | 53 | sql = delete.Where(items).ToSql().Replace("\r\n", ""); 54 | Assert.Equal("DELETE FROM [tb_topic22211] WHERE ([Id] IN (1,2,3,4,5,6,7,8,9,10))", sql); 55 | } 56 | [Fact] 57 | public void WhereExists() { 58 | 59 | } 60 | [Fact] 61 | public void ExecuteAffrows() { 62 | 63 | var id = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); 64 | Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); 65 | } 66 | [Fact] 67 | public void ExecuteDeleted() { 68 | 69 | var item = g.sqlserver.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); 70 | Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /FreeSql.Tests/SqlServer/SqlServerAdo/SqlServerAdoTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.SqlServer { 6 | public class SqlServerAdoTest { 7 | [Fact] 8 | public void Pool() { 9 | var t1 = g.sqlserver.Ado.MasterPool.StatisticsFullily; 10 | } 11 | 12 | [Fact] 13 | public void SlavePools() { 14 | var t2 = g.sqlserver.Ado.SlavePools.Count; 15 | } 16 | 17 | [Fact] 18 | public void ExecuteReader() { 19 | 20 | } 21 | [Fact] 22 | public void ExecuteArray() { 23 | 24 | } 25 | [Fact] 26 | public void ExecuteNonQuery() { 27 | 28 | } 29 | [Fact] 30 | public void ExecuteScalar() { 31 | 32 | } 33 | 34 | [Fact] 35 | public void Query() { 36 | var t3 = g.sqlserver.Ado.Query("select * from song"); 37 | 38 | var t4 = g.sqlserver.Ado.Query<(int, string, string, DateTime)>("select * from song"); 39 | 40 | var t5 = g.sqlserver.Ado.Query("select * from song"); 41 | } 42 | 43 | class xxx { 44 | public int Id { get; set; } 45 | public string Title { get; set; } 46 | public string Url { get; set; } 47 | public DateTime Create_time { get; set; } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YSGStudyHards/FreeSql/7e59e079567c84606ca0b74bcddd6d2d24d841fa/FreeSql.Tests/SqlServer/SqlServerCodeFirstTest.cs -------------------------------------------------------------------------------- /FreeSql.Tests/SqlServer/SqlServerDbFirstTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.SqlServer { 6 | public class SqlServerDbFirstTest { 7 | [Fact] 8 | public void GetDatabases() { 9 | 10 | var t1 = g.sqlserver.DbFirst.GetDatabases(); 11 | 12 | } 13 | 14 | [Fact] 15 | public void GetTablesByDatabase() { 16 | 17 | var t2 = g.sqlserver.DbFirst.GetTablesByDatabase(g.sqlserver.DbFirst.GetDatabases()[0]); 18 | 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /FreeSql.Tests/SqlServer/SqlServerExpression/OtherTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Linq; 4 | using Xunit; 5 | 6 | namespace FreeSql.Tests.SqlServerExpression { 7 | public class OtherTest { 8 | 9 | ISelect select => g.sqlserver.Select(); 10 | 11 | public OtherTest() { 12 | } 13 | 14 | 15 | [Fact] 16 | public void Array() { 17 | //in not in 18 | var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); 19 | //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.testFieldInt) == false).ToList(); 20 | var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.testFieldInt)).ToList(); 21 | 22 | var inarray = new[] { 1, 2, 3 }; 23 | var sql1111 = select.Where(a => inarray.Contains(a.testFieldInt)).ToList(); 24 | //var sql1122 = select.Where(a => inarray.Contains(a.testFieldInt) == false).ToList(); 25 | var sql1133 = select.Where(a => !inarray.Contains(a.testFieldInt)).ToList(); 26 | } 27 | 28 | [Table(Name = "tb_alltype")] 29 | class TableAllType { 30 | [Column(IsIdentity = true, IsPrimary = true)] 31 | public int Id { get; set; } 32 | 33 | [Column(Name = "testFieldBool1111")] 34 | public bool testFieldBool { get; set; } 35 | public sbyte testFieldSByte { get; set; } 36 | public short testFieldShort { get; set; } 37 | public int testFieldInt { get; set; } 38 | public long testFieldLong { get; set; } 39 | public byte testFieldByte { get; set; } 40 | public ushort testFieldUShort { get; set; } 41 | public uint testFieldUInt { get; set; } 42 | public ulong testFieldULong { get; set; } 43 | public double testFieldDouble { get; set; } 44 | public float testFieldFloat { get; set; } 45 | public decimal testFieldDecimal { get; set; } 46 | public TimeSpan testFieldTimeSpan { get; set; } 47 | public DateTime testFieldDateTime { get; set; } 48 | public DateTimeOffset testFieldDateTimeOffset { get; set; } 49 | public byte[] testFieldBytes { get; set; } 50 | public string testFieldString { get; set; } 51 | public Guid testFieldGuid { get; set; } 52 | 53 | public bool? testFieldBoolNullable { get; set; } 54 | public sbyte? testFieldSByteNullable { get; set; } 55 | public short? testFieldShortNullable { get; set; } 56 | public int? testFieldIntNullable { get; set; } 57 | public long? testFielLongNullable { get; set; } 58 | public byte? testFieldByteNullable { get; set; } 59 | public ushort? testFieldUShortNullable { get; set; } 60 | public uint? testFieldUIntNullable { get; set; } 61 | public ulong? testFieldULongNullable { get; set; } 62 | public double? testFieldDoubleNullable { get; set; } 63 | public float? testFieldFloatNullable { get; set; } 64 | public decimal? testFieldDecimalNullable { get; set; } 65 | public TimeSpan? testFieldTimeSpanNullable { get; set; } 66 | public DateTime? testFieldDateTimeNullable { get; set; } 67 | public DateTimeOffset? testFieldDateTimeNullableOffset { get; set; } 68 | public Guid? testFieldGuidNullable { get; set; } 69 | 70 | public TableAllTypeEnumType1 testFieldEnum1 { get; set; } 71 | public TableAllTypeEnumType1? testFieldEnum1Nullable { get; set; } 72 | public TableAllTypeEnumType2 testFieldEnum2 { get; set; } 73 | public TableAllTypeEnumType2? testFieldEnum2Nullable { get; set; } 74 | } 75 | 76 | public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } 77 | [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /FreeSql.Tests/Sqlite/Curd/SqliteDeleteTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using Xunit; 6 | 7 | namespace FreeSql.Tests.Sqlite { 8 | public class SqliteDeleteTest { 9 | 10 | IDelete delete => g.sqlite.Delete(); //�������� 11 | 12 | [Table(Name = "tb_topic22211")] 13 | class Topic { 14 | [Column(IsIdentity = true, IsPrimary = true)] 15 | public int Id { get; set; } 16 | public int? Clicks { get; set; } 17 | public TestTypeInfo Type { get; set; } 18 | public string Title { get; set; } 19 | public DateTime CreateTime { get; set; } 20 | } 21 | 22 | [Fact] 23 | public void Dywhere() { 24 | Assert.Null(g.sqlite.Delete().ToSql()); 25 | var sql = g.sqlite.Delete(new[] { 1, 2 }).ToSql(); 26 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); 27 | 28 | sql = g.sqlite.Delete(new Topic { Id = 1, Title = "test" }).ToSql(); 29 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 30 | 31 | sql = g.sqlite.Delete(new[] { new Topic { Id = 1, Title = "test" }, new Topic { Id = 2, Title = "test" } }).ToSql(); 32 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1 OR \"Id\" = 2)", sql); 33 | 34 | sql = g.sqlite.Delete(new { id = 1 }).ToSql(); 35 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 36 | } 37 | 38 | [Fact] 39 | public void Where() { 40 | var sql = delete.Where(a => a.Id == 1).ToSql().Replace("\r\n", ""); 41 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 42 | 43 | sql = delete.Where("id = ?id", new { id = 1 }).ToSql().Replace("\r\n", ""); 44 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (id = ?id)", sql); 45 | 46 | var item = new Topic { Id = 1, Title = "newtitle" }; 47 | sql = delete.Where(item).ToSql().Replace("\r\n", ""); 48 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" = 1)", sql); 49 | 50 | var items = new List(); 51 | for (var a = 0; a < 10; a++) items.Add(new Topic { Id = a + 1, Title = $"newtitle{a}", Clicks = a * 100 }); 52 | 53 | sql = delete.Where(items).ToSql().Replace("\r\n", ""); 54 | Assert.Equal("DELETE FROM \"tb_topic22211\" WHERE (\"Id\" IN (1,2,3,4,5,6,7,8,9,10))", sql); 55 | } 56 | [Fact] 57 | public void WhereExists() { 58 | 59 | } 60 | [Fact] 61 | public void ExecuteAffrows() { 62 | 63 | var id = g.sqlite.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteIdentity(); 64 | Assert.Equal(1, delete.Where(a => a.Id == id).ExecuteAffrows()); 65 | } 66 | [Fact] 67 | public void ExecuteDeleted() { 68 | 69 | //var item = g.Sqlite.Insert(new Topic { Title = "xxxx", CreateTime = DateTime.Now }).ExecuteInserted(); 70 | //Assert.Equal(item[0].Id, delete.Where(a => a.Id == item[0].Id).ExecuteDeleted()[0].Id); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /FreeSql.Tests/Sqlite/SqliteAdo/SqliteAdoTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using Xunit; 4 | 5 | namespace FreeSql.Tests.Sqlite { 6 | public class SqliteAdoTest { 7 | [Fact] 8 | public void Pool() { 9 | var t1 = g.sqlite.Ado.MasterPool.StatisticsFullily; 10 | } 11 | 12 | [Fact] 13 | public void SlavePools() { 14 | var t2 = g.sqlite.Ado.SlavePools.Count; 15 | } 16 | [Fact] 17 | public void ExecuteReader() { 18 | 19 | } 20 | [Fact] 21 | public void ExecuteArray() { 22 | 23 | } 24 | [Fact] 25 | public void ExecuteNonQuery() { 26 | 27 | } 28 | [Fact] 29 | public void ExecuteScalar() { 30 | 31 | } 32 | 33 | [Fact] 34 | public void Query() { 35 | var t3 = g.sqlite.Ado.Query("select * from \"song\""); 36 | 37 | var t4 = g.sqlite.Ado.Query<(int, string, string)>("select * from \"song\""); 38 | 39 | var t5 = g.sqlite.Ado.Query("select * from \"song\""); 40 | } 41 | 42 | class xxx { 43 | public int Id { get; set; } 44 | public string Path { get; set; } 45 | public string Title2 { get; set; } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YSGStudyHards/FreeSql/7e59e079567c84606ca0b74bcddd6d2d24d841fa/FreeSql.Tests/Sqlite/SqliteCodeFirstTest.cs -------------------------------------------------------------------------------- /FreeSql.Tests/Sqlite/SqliteExpression/OtherTest.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | using System.Linq; 4 | using Xunit; 5 | 6 | namespace FreeSql.Tests.SqliteExpression { 7 | public class OtherTest { 8 | 9 | ISelect select => g.sqlite.Select(); 10 | 11 | public OtherTest() { 12 | } 13 | 14 | 15 | [Fact] 16 | public void Array() { 17 | //in not in 18 | var sql111 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); 19 | //var sql112 = select.Where(a => new[] { 1, 2, 3 }.Contains(a.Int) == false).ToList(); 20 | var sql113 = select.Where(a => !new[] { 1, 2, 3 }.Contains(a.Int)).ToList(); 21 | 22 | var inarray = new[] { 1, 2, 3 }; 23 | var sql1111 = select.Where(a => inarray.Contains(a.Int)).ToList(); 24 | //var sql1122 = select.Where(a => inarray.Contains(a.Int) == false).ToList(); 25 | var sql1133 = select.Where(a => !inarray.Contains(a.Int)).ToList(); 26 | } 27 | 28 | [Table(Name = "tb_alltype")] 29 | class TableAllType { 30 | [Column(IsIdentity = true, IsPrimary = true)] 31 | public int Id { get; set; } 32 | 33 | public string id2 { get; set; } = "id2=10"; 34 | 35 | public bool Bool { get; set; } 36 | public sbyte SByte { get; set; } 37 | public short Short { get; set; } 38 | public int Int { get; set; } 39 | public long Long { get; set; } 40 | public byte Byte { get; set; } 41 | public ushort UShort { get; set; } 42 | public uint UInt { get; set; } 43 | public ulong ULong { get; set; } 44 | public double Double { get; set; } 45 | public float Float { get; set; } 46 | public decimal Decimal { get; set; } 47 | public TimeSpan TimeSpan { get; set; } 48 | public DateTime DateTime { get; set; } 49 | public DateTime DateTimeOffSet { get; set; } 50 | public byte[] Bytes { get; set; } 51 | public string String { get; set; } 52 | public Guid Guid { get; set; } 53 | 54 | public bool? BoolNullable { get; set; } 55 | public sbyte? SByteNullable { get; set; } 56 | public short? ShortNullable { get; set; } 57 | public int? IntNullable { get; set; } 58 | public long? testFielLongNullable { get; set; } 59 | public byte? ByteNullable { get; set; } 60 | public ushort? UShortNullable { get; set; } 61 | public uint? UIntNullable { get; set; } 62 | public ulong? ULongNullable { get; set; } 63 | public double? DoubleNullable { get; set; } 64 | public float? FloatNullable { get; set; } 65 | public decimal? DecimalNullable { get; set; } 66 | public TimeSpan? TimeSpanNullable { get; set; } 67 | public DateTime? DateTimeNullable { get; set; } 68 | public DateTime? DateTimeOffSetNullable { get; set; } 69 | public Guid? GuidNullable { get; set; } 70 | 71 | public TableAllTypeEnumType1 Enum1 { get; set; } 72 | public TableAllTypeEnumType1? Enum1Nullable { get; set; } 73 | public TableAllTypeEnumType2 Enum2 { get; set; } 74 | public TableAllTypeEnumType2? Enum2Nullable { get; set; } 75 | } 76 | 77 | public enum TableAllTypeEnumType1 { e1, e2, e3, e5 } 78 | [Flags] public enum TableAllTypeEnumType2 { f1, f2, f3 } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /FreeSql.Tests/UnitTest1.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YSGStudyHards/FreeSql/7e59e079567c84606ca0b74bcddd6d2d24d841fa/FreeSql.Tests/UnitTest1.cs -------------------------------------------------------------------------------- /FreeSql.Tests/g.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Text; 5 | 6 | 7 | public class g { 8 | 9 | public static IFreeSql mysql = new FreeSql.FreeSqlBuilder() 10 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 11 | .UseAutoSyncStructure(true) 12 | 13 | .UseMonitorCommand( 14 | cmd => { 15 | Trace.WriteLine(cmd.CommandText); 16 | }, //监听SQL命令对象,在执行前 17 | (cmd, traceLog) => { 18 | Console.WriteLine(traceLog); 19 | }) //监听SQL命令对象,在执行后 20 | .UseLazyLoading(true) 21 | .Build(); 22 | 23 | public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() 24 | .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=.;Integrated Security=True;Initial Catalog=cms;Pooling=true;Max Pool Size=10") 25 | .UseAutoSyncStructure(true) 26 | .UseLazyLoading(true) 27 | .Build(); 28 | 29 | public static IFreeSql pgsql = new FreeSql.FreeSqlBuilder() 30 | .UseConnectionString(FreeSql.DataType.PostgreSQL, "Host=192.168.164.10;Port=5432;Username=postgres;Password=123456;Database=tedb;Pooling=true;Maximum Pool Size=10") 31 | .UseAutoSyncStructure(true) 32 | .UseSyncStructureToLower(true) 33 | .UseLazyLoading(true) 34 | .Build(); 35 | 36 | public static IFreeSql oracle = new FreeSql.FreeSqlBuilder() 37 | .UseConnectionString(FreeSql.DataType.Oracle, "user id=user1;password=123456;data source=//127.0.0.1:1521/XE;Pooling=true;Max Pool Size=10") 38 | .UseAutoSyncStructure(true) 39 | .UseLazyLoading(true) 40 | .Build(); 41 | 42 | public static IFreeSql sqlite = new FreeSql.FreeSqlBuilder() 43 | .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|\document.db;Attachs=xxxtb.db;Pooling=true;Max Pool Size=10") 44 | .UseAutoSyncStructure(true) 45 | .UseLazyLoading(true) 46 | .Build(); 47 | } 48 | -------------------------------------------------------------------------------- /FreeSql/DataAnnotations/ColumnAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FreeSql.DataAnnotations { 4 | public class ColumnAttribute : Attribute { 5 | 6 | /// 7 | /// 数据库列名 8 | /// 9 | public string Name { get; set; } 10 | /// 11 | /// 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 12 | /// 13 | public string OldName { get; set; } 14 | /// 15 | /// 数据库类型,如: varchar(255) 16 | /// 17 | public string DbType { get; set; } 18 | 19 | internal bool? _IsPrimary, _IsIdentity, _IsNullable; 20 | /// 21 | /// 主键 22 | /// 23 | public bool IsPrimary { get => _IsPrimary ?? false; set => _IsPrimary = value; } 24 | /// 25 | /// 自增标识 26 | /// 27 | public bool IsIdentity { get => _IsIdentity ?? false; set => _IsIdentity = value; } 28 | /// 29 | /// 是否可DBNull 30 | /// 31 | public bool IsNullable { get => _IsNullable ?? false; set => _IsNullable = value; } 32 | 33 | /// 34 | /// 数据库默认值 35 | /// 36 | internal object DbDefautValue { get; set; } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /FreeSql/DataAnnotations/ColumnFluent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FreeSql.DataAnnotations { 4 | public class ColumnFluent { 5 | 6 | public ColumnFluent(ColumnAttribute column) { 7 | _column = column; 8 | } 9 | 10 | ColumnAttribute _column; 11 | /// 12 | /// 数据库列名 13 | /// 14 | public ColumnFluent Name(string value) { 15 | _column.Name = value; 16 | return this; 17 | } 18 | /// 19 | /// 指定数据库旧的列名,修改实体属性命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库字段;否则将视为【新增字段】 20 | /// 21 | public ColumnFluent OldName(string value) { 22 | _column.OldName = value; 23 | return this; 24 | } 25 | /// 26 | /// 数据库类型,如: varchar(255) 27 | /// 28 | public ColumnFluent DbType(string value) { 29 | _column.DbType = value; 30 | return this; 31 | } 32 | 33 | /// 34 | /// 主键 35 | /// 36 | public ColumnFluent IsPrimary(bool value) { 37 | _column.IsPrimary = value; 38 | return this; 39 | } 40 | /// 自增标识 41 | /// 42 | public ColumnFluent IsIdentity(bool value) { 43 | _column.IsIdentity = value; 44 | return this; 45 | } 46 | /// 47 | /// 是否可DBNull 48 | /// 49 | public ColumnFluent IsNullable(bool value) { 50 | _column.IsNullable = value; 51 | return this; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /FreeSql/DataAnnotations/TableAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | 4 | namespace FreeSql.DataAnnotations { 5 | public class TableAttribute : Attribute { 6 | 7 | /// 8 | /// 数据库表名 9 | /// 10 | public string Name { get; set; } 11 | /// 12 | /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 13 | /// 14 | public string OldName { get; set; } 15 | /// 16 | /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 17 | /// 18 | public string SelectFilter { get; set; } 19 | 20 | internal ConcurrentDictionary _columns = new ConcurrentDictionary(StringComparer.CurrentCultureIgnoreCase); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FreeSql/DataAnnotations/TableFluent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Concurrent; 4 | using System.Linq.Expressions; 5 | 6 | namespace FreeSql.DataAnnotations { 7 | public class TableFluent { 8 | 9 | public TableFluent(TableAttribute table) { 10 | _table = table; 11 | } 12 | 13 | TableAttribute _table; 14 | /// 15 | /// 数据库表名 16 | /// 17 | public TableFluent Name(string value) { 18 | _table.Name = value; 19 | return this; 20 | } 21 | /// 22 | /// 指定数据库旧的表名,修改实体命名时,同时设置此参数为修改之前的值,CodeFirst才可以正确修改数据库表;否则将视为【创建新表】 23 | /// 24 | public TableFluent OldName(string value) { 25 | _table.OldName = value; 26 | return this; 27 | } 28 | /// 29 | /// 查询过滤SQL,实现类似 a.IsDeleted = 1 功能 30 | /// 31 | public TableFluent SelectFilter(string value) { 32 | _table.SelectFilter = value; 33 | return this; 34 | } 35 | 36 | public ColumnFluent Property(Expression> column) { 37 | var proto = (column.Body as MemberExpression)?.Member; 38 | if (proto == null) throw new FormatException($"错误的表达式格式 {column}"); 39 | var col = _table._columns.GetOrAdd(proto.Name, name => new ColumnAttribute { Name = proto.Name }); 40 | return new ColumnFluent(col); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /FreeSql/DatabaseModel/DBColumnInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace FreeSql.DatabaseModel { 6 | public class DbColumnInfo { 7 | /// 8 | /// 所属表 9 | /// 10 | public DbTableInfo Table { get; internal set; } 11 | /// 12 | /// 列名 13 | /// 14 | public string Name { get; internal set; } 15 | /// 16 | /// 映射到 C# 类型 17 | /// 18 | public Type CsType { get; internal set; } 19 | /// 20 | /// 数据库枚举类型int值 21 | /// 22 | public int DbType { get; internal set; } 23 | /// 24 | /// 数据库类型,字符串,varchar 25 | /// 26 | public string DbTypeText { get; internal set; } 27 | /// 28 | /// 数据库类型,字符串,varchar(255) 29 | /// 30 | public string DbTypeTextFull { get; internal set; } 31 | /// 32 | /// 最大长度 33 | /// 34 | public int MaxLength { get; internal set; } 35 | /// 36 | /// 主键 37 | /// 38 | public bool IsPrimary { get; internal set; } 39 | /// 40 | /// 自增标识 41 | /// 42 | public bool IsIdentity { get; internal set; } 43 | /// 44 | /// 是否可DBNull 45 | /// 46 | public bool IsNullable { get; internal set; } 47 | /// 48 | /// 备注 49 | /// 50 | public string Coment { get; internal set; } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /FreeSql/DatabaseModel/DBTableInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace FreeSql.DatabaseModel { 6 | public class DbTableInfo { 7 | /// 8 | /// 唯一标识 9 | /// 10 | public string Id { get; internal set; } 11 | /// 12 | /// SqlServer下是Owner、PostgreSQL下是Schema、MySql下是数据库名 13 | /// 14 | public string Schema { get; internal set; } 15 | /// 16 | /// 表名 17 | /// 18 | public string Name { get; internal set; } 19 | /// 20 | /// 表/视图 21 | /// 22 | public DbTableType Type { get; set; } 23 | /// 24 | /// 列 25 | /// 26 | public List Columns { get; internal set; } = new List(); 27 | /// 28 | /// 自增列 29 | /// 30 | public List Identitys { get; internal set; } = new List(); 31 | /// 32 | /// 主键/组合 33 | /// 34 | public List Primarys { get; internal set; } = new List(); 35 | /// 36 | /// 唯一键/组合 37 | /// 38 | public List> Uniques { get; internal set; } = new List>(); 39 | /// 40 | /// 索引/组合 41 | /// 42 | public List> Indexes { get; internal set; } = new List>(); 43 | /// 44 | /// 外键 45 | /// 46 | public List Foreigns { get; internal set; } = new List(); 47 | } 48 | 49 | public enum DbTableType { 50 | TABLE, VIEW, StoreProcedure 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /FreeSql/DatabaseModel/DbEnumInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace FreeSql.DatabaseModel { 6 | public class DbEnumInfo { 7 | 8 | /// 9 | /// 枚举类型标识 10 | /// 11 | public string Name { get; set; } 12 | 13 | /// 14 | /// 枚举项 15 | /// 16 | public Dictionary Labels { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FreeSql/DatabaseModel/DbForeignInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace FreeSql.DatabaseModel { 6 | public class DbForeignInfo { 7 | public DbTableInfo Table { get; internal set; } 8 | public List Columns { get; internal set; } = new List(); 9 | public DbTableInfo ReferencedTable { get; internal set; } 10 | public List ReferencedColumns { get; internal set; } = new List(); 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /FreeSql/DatabaseModel/DbTypeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace FreeSql.DatabaseModel { 6 | public class DbTypeInfo { 7 | 8 | /// 9 | /// 类型标识 10 | /// 11 | public string Name { get; set; } 12 | 13 | /// 14 | /// 枚举项 15 | /// 16 | public List<(string label, string value)> Labels { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /FreeSql/Extensions/FreeSqlGlobalExtensions.cs: -------------------------------------------------------------------------------- 1 | using NpgsqlTypes; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Data; 7 | using System.Drawing; 8 | using System.Linq; 9 | using System.Reflection; 10 | 11 | public static class FreeSqlGlobalExtensions { 12 | 13 | public static FreeSql.ISelect Queryable(this IFreeSql freesql) where T : class => freesql.Select(); 14 | 15 | static Lazy> dicIsNumberType = new Lazy>(() => new Dictionary { 16 | [typeof(sbyte)] = true, 17 | [typeof(short)] = true, 18 | [typeof(int)] = true, 19 | [typeof(long)] = true, 20 | [typeof(byte)] = true, 21 | [typeof(ushort)] = true, 22 | [typeof(uint)] = true, 23 | [typeof(ulong)] = true, 24 | [typeof(double)] = true, 25 | [typeof(float)] = true, 26 | [typeof(decimal)] = true 27 | }); 28 | public static bool IsNumberType(this Type that) => that == null ? false : dicIsNumberType.Value.ContainsKey(that.GenericTypeArguments.FirstOrDefault() ?? that); 29 | 30 | /// 31 | /// 测量两个经纬度的距离,返回单位:米 32 | /// 33 | /// 经纬坐标1 34 | /// 经纬坐标2 35 | /// 返回距离(单位:米) 36 | public static double Distance(this Point that, Point point) { 37 | double radLat1 = (double)(that.Y) * Math.PI / 180d; 38 | double radLng1 = (double)(that.X) * Math.PI / 180d; 39 | double radLat2 = (double)(point.Y) * Math.PI / 180d; 40 | double radLng2 = (double)(point.X) * Math.PI / 180d; 41 | return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137; 42 | } 43 | 44 | public static object GetEnum(this IDataReader dr, int index) { 45 | string value = dr.GetString(index); 46 | Type t = typeof(T); 47 | foreach (var f in t.GetFields()) 48 | if (f.GetCustomAttribute()?.Description == value || f.Name == value) return Enum.Parse(t, f.Name, true); 49 | return null; 50 | } 51 | 52 | public static string ToDescriptionOrString(this Enum item) { 53 | string name = item.ToString(); 54 | var desc = item.GetType().GetField(name)?.GetCustomAttribute(); 55 | return desc?.Description ?? name; 56 | } 57 | public static long ToInt64(this Enum item) { 58 | return Convert.ToInt64(item); 59 | } 60 | public static IEnumerable ToSet(this long value) { 61 | List ret = new List(); 62 | if (value == 0) return ret; 63 | Type t = typeof(T); 64 | foreach (FieldInfo f in t.GetFields()) { 65 | if (f.FieldType != t) continue; 66 | object o = Enum.Parse(t, f.Name, true); 67 | long v = (long)o; 68 | if ((value & v) == v) ret.Add((T)o); 69 | } 70 | return ret; 71 | } 72 | } -------------------------------------------------------------------------------- /FreeSql/Extensions/FreeSqlStringExtensions.cs: -------------------------------------------------------------------------------- 1 | public static class FreeSqlStringExtensions { 2 | 3 | /// 4 | /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 5 | /// 6 | /// 7 | /// 8 | /// 9 | public static string FormatMySql(this string that, params object[] args) => _mysqlAdo.Addslashes(that, args); 10 | static FreeSql.MySql.MySqlAdo _mysqlAdo = new FreeSql.MySql.MySqlAdo(); 11 | /// 12 | /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 13 | /// 14 | /// 15 | /// 16 | /// 17 | public static string FormatSqlServer(this string that, params object[] args) => _sqlserverAdo.Addslashes(that, args); 18 | static FreeSql.SqlServer.SqlServerAdo _sqlserverAdo = new FreeSql.SqlServer.SqlServerAdo(); 19 | /// 20 | /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 21 | /// 22 | /// 23 | /// 24 | /// 25 | public static string FormatPostgreSQL(this string that, params object[] args) => _postgresqlAdo.Addslashes(that, args); 26 | static FreeSql.PostgreSQL.PostgreSQLAdo _postgresqlAdo = new FreeSql.PostgreSQL.PostgreSQLAdo(); 27 | /// 28 | /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 29 | /// 30 | /// 31 | /// 32 | /// 33 | public static string FormatOracleSQL(this string that, params object[] args) => _oracleAdo.Addslashes(that, args); 34 | static FreeSql.Oracle.OracleAdo _oracleAdo = new FreeSql.Oracle.OracleAdo(); 35 | /// 36 | /// 特殊处理类似 string.Format 的使用方法,防止注入,以及 IS NULL 转换 37 | /// 38 | /// 39 | /// 40 | /// 41 | public static string FormatSqlite (this string that, params object[] args) => _sqliteAdo.Addslashes(that, args); 42 | static FreeSql.Sqlite.SqliteAdo _sqliteAdo = new FreeSql.Sqlite.SqliteAdo(); 43 | } 44 | 45 | namespace System.Runtime.CompilerServices { 46 | public class ExtensionAttribute : Attribute { } 47 | } -------------------------------------------------------------------------------- /FreeSql/FreeSql.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 0.0.9 6 | true 7 | YeXiangQin 8 | 打造 .NETCore 最方便的 ORM,DbFirst 与 CodeFirst 混合使用,提供从实体同步数据库,或者从数据库生成实体代码,支持 MySql/SqlServer/PostgreSQL/Oracle/Sqlite 数据库。 9 | https://github.com/2881099/FreeSql 10 | FreeSql ORM 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /FreeSql/FreeUtil.cs: -------------------------------------------------------------------------------- 1 | using NpgsqlTypes; 2 | using System; 3 | using System.Collections; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading; 9 | 10 | public static class FreeUtil { 11 | 12 | private static DateTime dt1970 = new DateTime(1970, 1, 1); 13 | private static ThreadLocal rnd = new ThreadLocal(); 14 | private static readonly int __staticMachine = ((0x00ffffff & Environment.MachineName.GetHashCode()) + 15 | #if NETSTANDARD1_5 || NETSTANDARD1_6 16 | 1 17 | #else 18 | AppDomain.CurrentDomain.Id 19 | #endif 20 | ) & 0x00ffffff; 21 | private static readonly int __staticPid = Process.GetCurrentProcess().Id; 22 | private static int __staticIncrement = rnd.Value.Next(); 23 | /// 24 | /// 生成类似Mongodb的ObjectId有序、不重复Guid 25 | /// 26 | /// 27 | public static Guid NewMongodbId() { 28 | var now = DateTime.Now; 29 | var uninxtime = (int)now.Subtract(dt1970).TotalSeconds; 30 | int increment = Interlocked.Increment(ref __staticIncrement) & 0x00ffffff; 31 | var rand = rnd.Value.Next(0, int.MaxValue); 32 | var guid = $"{uninxtime.ToString("x8").PadLeft(8, '0')}{__staticMachine.ToString("x8").PadLeft(8, '0').Substring(2, 6)}{__staticPid.ToString("x8").PadLeft(8, '0').Substring(6, 2)}{increment.ToString("x8").PadLeft(8, '0')}{rand.ToString("x8").PadLeft(8, '0')}"; 33 | return Guid.Parse(guid); 34 | } 35 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/IDelete.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface IDelete where T1 : class { 8 | /// 9 | /// lambda表达式条件,仅支持实体基础成员(不包含导航对象) 10 | /// 11 | /// lambda表达式条件 12 | /// 13 | IDelete Where(Expression> exp); 14 | /// 15 | /// 原生sql语法条件,Where("id = ?id", new { id = 1 }) 16 | /// 17 | /// sql语法条件 18 | /// 参数 19 | /// 20 | IDelete Where(string sql, object parms = null); 21 | /// 22 | /// 传入实体,将主键作为条件 23 | /// 24 | /// 实体 25 | /// 26 | IDelete Where(T1 item); 27 | /// 28 | /// 传入实体集合,将主键作为条件 29 | /// 30 | /// 实体集合 31 | /// 32 | IDelete Where(IEnumerable items); 33 | /// 34 | /// 子查询是否存在 35 | /// 36 | /// 37 | /// 子查询 38 | /// 不存在 39 | /// 40 | IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class; 41 | 42 | /// 43 | /// 返回即将执行的SQL语句 44 | /// 45 | /// 46 | string ToSql(); 47 | /// 48 | /// 执行SQL语句,返回影响的行数 49 | /// 50 | /// 51 | int ExecuteAffrows(); 52 | Task ExecuteAffrowsAsync(); 53 | /// 54 | /// 执行SQL语句,返回被删除的记录 55 | /// 56 | /// 57 | List ExecuteDeleted(); 58 | Task> ExecuteDeletedAsync(); 59 | } 60 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/IInsert.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface IInsert where T1 : class { 8 | 9 | /// 10 | /// 追加准备插入的实体 11 | /// 12 | /// 实体 13 | /// 14 | IInsert AppendData(T1 source); 15 | /// 16 | /// 追加准备插入的实体集合 17 | /// 18 | /// 实体集合 19 | /// 20 | IInsert AppendData(IEnumerable source); 21 | 22 | /// 23 | /// 只插入的列,InsertColumns(a => a.Name) | InsertColumns(a => new{a.Name,a.Time}) | InsertColumns(a => new[]{"name","time"}) 24 | /// 25 | /// lambda选择列 26 | /// 27 | IInsert InsertColumns(Expression> columns); 28 | /// 29 | /// 忽略的列,IgnoreColumns(a => a.Name) | IgnoreColumns(a => new{a.Name,a.Time}) | IgnoreColumns(a => new[]{"name","time"}) 30 | /// 31 | /// lambda选择列 32 | /// 33 | IInsert IgnoreColumns(Expression> columns); 34 | 35 | /// 36 | /// 返回即将执行的SQL语句 37 | /// 38 | /// 39 | string ToSql(); 40 | /// 41 | /// 执行SQL语句,返回影响的行数 42 | /// 43 | /// 44 | int ExecuteAffrows(); 45 | Task ExecuteAffrowsAsync(); 46 | /// 47 | /// 执行SQL语句,返回自增值 48 | /// 49 | /// 50 | long ExecuteIdentity(); 51 | Task ExecuteIdentityAsync(); 52 | /// 53 | /// 执行SQL语句,返回插入后的记录 54 | /// 55 | /// 56 | List ExecuteInserted(); 57 | Task> ExecuteInsertedAsync(); 58 | } 59 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect10.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect3.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect4.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect5.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect6.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect7.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect8.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelect9.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Threading.Tasks; 5 | 6 | namespace FreeSql { 7 | public interface ISelect : ISelect0, T1> where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class { 8 | 9 | List ToList(Expression> select); 10 | Task> ToListAsync(Expression> select); 11 | string ToSql(Expression> select); 12 | 13 | TReturn ToAggregate(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 14 | Task ToAggregateAsync(Expression, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, ISelectGroupingAggregate, TReturn>> select); 15 | 16 | TMember Sum(Expression> column); 17 | Task SumAsync(Expression> column); 18 | TMember Min(Expression> column); 19 | Task MinAsync(Expression> column); 20 | TMember Max(Expression> column); 21 | Task MaxAsync(Expression> column); 22 | TMember Avg(Expression> column); 23 | Task AvgAsync(Expression> column); 24 | 25 | ISelect Where(Expression> exp); 26 | ISelect WhereIf(bool condition, Expression> exp); 27 | 28 | ISelectGrouping GroupBy(Expression> exp); 29 | 30 | ISelect OrderBy(Expression> column); 31 | ISelect OrderByDescending(Expression> column); 32 | } 33 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelectFrom.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | 5 | namespace FreeSql { 6 | public interface ISelectFromExpression where T1 : class { 7 | 8 | ISelectFromExpression LeftJoin(Expression> exp); 9 | ISelectFromExpression InnerJoin(Expression> exp); 10 | ISelectFromExpression RightJoin(Expression> exp); 11 | 12 | /// 13 | /// 查询条件,Where(a => a.Id > 10),支持导航对象查询,Where(a => a.Author.Email == "2881099@qq.com") 14 | /// 15 | /// lambda表达式 16 | /// 17 | ISelectFromExpression Where(Expression> exp); 18 | /// 19 | /// 查询条件,Where(true, a => a.Id > 10),支导航对象查询,Where(true, a => a.Author.Email == "2881099@qq.com") 20 | /// 21 | /// true 时生效 22 | /// lambda表达式 23 | /// 24 | ISelectFromExpression WhereIf(bool condition, Expression> exp); 25 | 26 | /// 27 | /// 按列排序,OrderBy(a => a.Time) 28 | /// 29 | /// 30 | /// 31 | /// 32 | ISelectFromExpression OrderBy(Expression> column); 33 | /// 34 | /// 按列倒向排序,OrderByDescending(a => a.Time) 35 | /// 36 | /// 列 37 | /// 38 | ISelectFromExpression OrderByDescending(Expression> column); 39 | } 40 | } -------------------------------------------------------------------------------- /FreeSql/Interface/Curd/ISelect/ISelectGrouping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FreeSql { 8 | public interface ISelectGrouping { 9 | /// 10 | /// 按聚合条件过滤,Where(a => a.Count() > 10) 11 | /// 12 | /// lambda表达式 13 | /// 14 | ISelectGrouping Having(Expression, bool>> exp); 15 | 16 | /// 17 | /// 按列排序,OrderBy(a => a.Time) 18 | /// 19 | /// 20 | /// 21 | /// 22 | ISelectGrouping OrderBy(Expression, TMember>> column); 23 | /// 24 | /// 按列倒向排序,OrderByDescending(a => a.Time) 25 | /// 26 | /// 列 27 | /// 28 | ISelectGrouping OrderByDescending(Expression, TMember>> column); 29 | 30 | /// 31 | /// 执行SQL查询,返回指定字段的记录,记录不存在时返回 Count 为 0 的列表 32 | /// 33 | /// 返回类型 34 | /// 选择列 35 | /// 36 | List ToList(Expression, TReturn>> select); 37 | Task> ToListAsync(Expression, TReturn>> select); 38 | 39 | /// 40 | /// 返回即将执行的SQL语句 41 | /// 42 | /// 返回类型 43 | /// 选择列 44 | /// 45 | string ToSql(Expression, TReturn>> select); 46 | } 47 | 48 | public interface ISelectGroupingAggregate { 49 | /// 50 | /// 分组的数据 51 | /// 52 | T1 Key { get; set; } 53 | /// 54 | /// 记录总数 55 | /// 56 | /// 57 | int Count(); 58 | /// 59 | /// 求和 60 | /// 61 | /// 62 | /// 63 | /// 64 | T3 Sum(T3 column); 65 | /// 66 | /// 平均值 67 | /// 68 | /// 69 | /// 70 | /// 71 | T3 Avg(T3 column); 72 | /// 73 | /// 最大值 74 | /// 75 | /// 76 | /// 77 | /// 78 | T3 Max(T3 column); 79 | /// 80 | /// 最小值 81 | /// 82 | /// 83 | /// 84 | T3 Min(T3 column); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /FreeSql/Interface/IAop.cs: -------------------------------------------------------------------------------- 1 | //using FreeSql.DatabaseModel; 2 | //using System; 3 | //using System.Collections.Generic; 4 | 5 | //namespace FreeSql { 6 | // public interface IAop { 7 | 8 | // ISelect SelectFitler(ISelect select) where T1 : class; 9 | // //ISelect SelectFitler(ISelect select) where T1 : class where T2 : class where T3 : class; 10 | // //ISelect SelectFitler(ISelect select) where T1 : class where T2 : class where T3 : class where T4 : class; 11 | // //ISelect SelectFitler(ISelect select) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class; 12 | // //ISelect SelectFitler(ISelect select) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class; 13 | // //ISelect SelectFitler(ISelect select) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class; 14 | // //ISelect SelectFitler(ISelect select) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class; 15 | // //ISelect SelectFitler(ISelect select) where T1 : class where T2 : class where T3 : class where T4 : class where T5 : class where T6 : class where T7 : class where T8 : class where T9 : class where T10 : class; 16 | 17 | // IUpdate UpdateFitler(IUpdate update) where T1 : class; 18 | // IDelete DeleteFitler(IUpdate delete) where T1 : class; 19 | // } 20 | //} 21 | -------------------------------------------------------------------------------- /FreeSql/Interface/ICodeFirst.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | 4 | namespace FreeSql { 5 | public interface ICodeFirst { 6 | 7 | /// 8 | /// 【开发环境必备】自动同步实体结构到数据库,程序运行中检查实体表是否存在,然后创建或修改 9 | /// 10 | bool IsAutoSyncStructure { get; set; } 11 | 12 | /// 13 | /// 转小写同步结构 14 | /// 15 | bool IsSyncStructureToLower { get; set; } 16 | /// 17 | /// 延时加载导航属性对象,导航属性需要声明 virtual 18 | /// 19 | bool IsLazyLoading { get; set; } 20 | 21 | /// 22 | /// 将实体类型与数据库对比,返回DDL语句 23 | /// 24 | /// 25 | /// 26 | string GetComparisonDDLStatements(); 27 | /// 28 | /// 将实体类型集合与数据库对比,返回DDL语句 29 | /// 30 | /// 31 | /// 32 | string GetComparisonDDLStatements(params Type[] entityTypes); 33 | /// 34 | /// 同步实体类型到数据库 35 | /// 36 | /// 37 | /// 38 | bool SyncStructure(); 39 | /// 40 | /// 同步实体类型集合到数据库 41 | /// 42 | /// 43 | /// 44 | bool SyncStructure(params Type[] entityTypes); 45 | 46 | /// 47 | /// 根据 System.Type 获取数据库信息 48 | /// 49 | /// 50 | /// 51 | (int type, string dbtype, string dbtypeFull, bool? isnullable, object defaultValue)? GetDbInfo(Type type); 52 | ICodeFirst ConfigEntity(Action> entity); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /FreeSql/Interface/IFreeSql.cs: -------------------------------------------------------------------------------- 1 | using FreeSql; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Text; 6 | 7 | public interface IFreeSql { 8 | /// 9 | /// 插入数据 10 | /// 11 | /// 12 | /// 13 | IInsert Insert() where T1 : class; 14 | /// 15 | /// 插入数据,传入实体 16 | /// 17 | /// 18 | /// 19 | /// 20 | IInsert Insert(T1 source) where T1 : class; 21 | /// 22 | /// 插入数据,传入实体集合 23 | /// 24 | /// 25 | /// 26 | /// 27 | IInsert Insert(IEnumerable source) where T1 : class; 28 | 29 | /// 30 | /// 修改数据 31 | /// 32 | /// 33 | /// 34 | IUpdate Update() where T1 : class; 35 | /// 36 | /// 修改数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 37 | /// 38 | /// 39 | /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 40 | /// 41 | IUpdate Update(object dywhere) where T1 : class; 42 | 43 | /// 44 | /// 查询数据 45 | /// 46 | /// 47 | /// 48 | ISelect Select() where T1 : class; 49 | /// 50 | /// 查询数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 51 | /// 52 | /// 53 | /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 54 | /// 55 | ISelect Select(object dywhere) where T1 : class; 56 | 57 | /// 58 | /// 删除数据 59 | /// 60 | /// 61 | /// 62 | IDelete Delete() where T1 : class; 63 | /// 64 | /// 删除数据,传入动态对象如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} 65 | /// 66 | /// 67 | /// 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 68 | /// 69 | IDelete Delete(object dywhere) where T1 : class; 70 | 71 | /// 72 | /// 开启事务(不支持异步),60秒未执行完将自动提交 73 | /// 74 | /// 事务体 () => {} 75 | void Transaction(Action handler); 76 | /// 77 | /// 开启事务(不支持异步) 78 | /// 79 | /// 事务体 () => {} 80 | /// 超时,未执行完将自动提交 81 | void Transaction(Action handler, TimeSpan timeout); 82 | 83 | /// 84 | /// 缓存 85 | /// 86 | ICache Cache { get; } 87 | /// 88 | /// 数据库访问对象 89 | /// 90 | IAdo Ado { get; } 91 | 92 | /// 93 | /// CodeFirst 模式开发相关方法 94 | /// 95 | ICodeFirst CodeFirst { get; } 96 | /// 97 | /// DbFirst 模式开发相关方法 98 | /// 99 | IDbFirst DbFirst { get; } 100 | } -------------------------------------------------------------------------------- /FreeSql/Interface/iDbFirst.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DatabaseModel; 2 | using System; 3 | using System.Collections.Generic; 4 | 5 | namespace FreeSql { 6 | public interface IDbFirst { 7 | 8 | /// 9 | /// 获取所有数据库 10 | /// 11 | /// 12 | List GetDatabases(); 13 | /// 14 | /// 获取指定数据库的表信息,包括表、列详情、主键、唯一键、索引、外键 15 | /// 16 | /// 17 | /// 18 | List GetTablesByDatabase(params string[] database); 19 | 20 | /// 21 | /// 获取数据库枚举类型int值 22 | /// 23 | /// 24 | /// 25 | int GetDbType(DbColumnInfo column); 26 | 27 | /// 28 | /// 获取c#转换,(int)、(long) 29 | /// 30 | /// 31 | /// 32 | string GetCsConvert(DbColumnInfo column); 33 | /// 34 | /// 获取c#值 35 | /// 36 | /// 37 | /// 38 | string GetCsTypeValue(DbColumnInfo column); 39 | /// 40 | /// 获取c#类型,int、long 41 | /// 42 | /// 43 | /// 44 | string GetCsType(DbColumnInfo column); 45 | /// 46 | /// 获取c#类型对象 47 | /// 48 | /// 49 | /// 50 | Type GetCsTypeInfo(DbColumnInfo column); 51 | /// 52 | /// 获取ado.net读取方法, GetBoolean、GetInt64 53 | /// 54 | /// 55 | /// 56 | string GetDataReaderMethod(DbColumnInfo column); 57 | /// 58 | /// 序列化 59 | /// 60 | /// 61 | /// 62 | string GetCsStringify(DbColumnInfo column); 63 | /// 64 | /// 反序列化 65 | /// 66 | /// 67 | /// 68 | string GetCsParse(DbColumnInfo column); 69 | 70 | /// 71 | /// 获取数据库枚举类型,适用 PostgreSQL 72 | /// 73 | /// 74 | /// 75 | List GetEnumsByDatabase(params string[] database); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /FreeSql/Internal/CommonProvider/AdoProvider/AdoProviderUtils.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace FreeSql.Internal.CommonProvider { 4 | partial class AdoProvider { 5 | 6 | public abstract object AddslashesProcessParam(object param); 7 | public string Addslashes(string filter, params object[] parms) { 8 | if (filter == null || parms == null) return string.Empty; 9 | if (parms.Length == 0) return filter; 10 | var nparms = new object[parms.Length]; 11 | for (int a = 0; a < parms.Length; a++) { 12 | if (parms[a] == null) 13 | filter = Regex.Replace(filter, @"\s*(=|IN)\s*\{" + a + @"\}", " IS {" + a + "}", RegexOptions.IgnoreCase); 14 | nparms[a] = AddslashesProcessParam(parms[a]); 15 | } 16 | try { string ret = string.Format(filter, nparms); return ret; } catch { return filter; } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /FreeSql/Internal/CommonProvider/DeleteProvider.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal.Model; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Data.Common; 6 | using System.Linq.Expressions; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace FreeSql.Internal.CommonProvider { 11 | 12 | abstract partial class DeleteProvider : IDelete where T1 : class { 13 | protected IFreeSql _orm; 14 | protected CommonUtils _commonUtils; 15 | protected CommonExpression _commonExpression; 16 | protected List _source = new List(); 17 | protected TableInfo _table; 18 | protected StringBuilder _where = new StringBuilder(); 19 | protected int _whereTimes = 0; 20 | protected List _params = new List(); 21 | 22 | public DeleteProvider(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) { 23 | _orm = orm; 24 | _commonUtils = commonUtils; 25 | _commonExpression = commonExpression; 26 | _table = _commonUtils.GetTableByEntity(typeof(T1)); 27 | _where.Append("DELETE FROM ").Append(_commonUtils.QuoteSqlName(_table.DbName)).Append(" WHERE "); 28 | this.Where(_commonUtils.WhereObject(_table, "", dywhere)); 29 | if (_orm.CodeFirst.IsAutoSyncStructure) _orm.CodeFirst.SyncStructure(); 30 | } 31 | 32 | public int ExecuteAffrows() { 33 | var sql = this.ToSql(); 34 | if (string.IsNullOrEmpty(sql)) return 0; 35 | return _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params.ToArray()); 36 | } 37 | async public Task ExecuteAffrowsAsync() { 38 | var sql = this.ToSql(); 39 | if (string.IsNullOrEmpty(sql)) return 0; 40 | return await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params.ToArray()); 41 | } 42 | public abstract List ExecuteDeleted(); 43 | public abstract Task> ExecuteDeletedAsync(); 44 | 45 | public IDelete Where(Expression> exp) => this.Where(_commonExpression.ExpressionWhereLambdaNoneForeignObject(null, null, exp?.Body, null)); 46 | public IDelete Where(string sql, object parms = null) { 47 | if (string.IsNullOrEmpty(sql)) return this; 48 | if (++_whereTimes > 1) _where.Append(" AND "); 49 | _where.Append("(").Append(sql).Append(")"); 50 | if (parms != null) _params.AddRange(_commonUtils.GetDbParamtersByObject(sql, parms)); 51 | return this; 52 | } 53 | public IDelete Where(T1 item) => this.Where(new[] { item }); 54 | public IDelete Where(IEnumerable items) => this.Where(_commonUtils.WhereItems(_table, "", items)); 55 | public IDelete WhereExists(ISelect select, bool notExists = false) where TEntity2 : class => this.Where($"{(notExists ? "NOT " : "")}EXISTS({select.ToSql("1")})"); 56 | 57 | public string ToSql() => _whereTimes <= 0 ? null : _where.ToString(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /FreeSql/Internal/Model/ColumnInfo.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.DataAnnotations; 2 | using System; 3 | 4 | namespace FreeSql.Internal.Model { 5 | class ColumnInfo { 6 | public TableInfo Table { get; set; } 7 | public string CsName { get; set; } 8 | public Type CsType { get; set; } 9 | public ColumnAttribute Attribute { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /FreeSql/Internal/Model/ReadAnonymousTypeInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | using System.Text; 5 | 6 | namespace FreeSql.Internal.Model { 7 | class ReadAnonymousTypeInfo { 8 | public PropertyInfo Property { get; set; } 9 | public string CsName { get; set; } 10 | public Type CsType { get; set; } 11 | public string DbField { get; set; } 12 | public ConstructorInfo Consturctor { get; set; } 13 | public ReadAnonymousTypeInfoConsturctorType ConsturctorType { get; set; } 14 | public List Childs = new List(); 15 | } 16 | enum ReadAnonymousTypeInfoConsturctorType { Arguments, Properties } 17 | } 18 | -------------------------------------------------------------------------------- /FreeSql/Internal/Model/SelectColumnInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace FreeSql.Internal.Model { 6 | class SelectColumnInfo { 7 | public ColumnInfo Column { get; set; } 8 | public SelectTableInfo Table { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /FreeSql/Internal/Model/SelectTableInfo.cs: -------------------------------------------------------------------------------- 1 | namespace FreeSql.Internal.Model { 2 | class SelectTableInfo { 3 | public TableInfo Table { get; set; } 4 | public string Alias { get; set; } 5 | public string On { get; set; } 6 | public SelectTableInfoType Type { get; set; } 7 | } 8 | enum SelectTableInfoType { From, LeftJoin, InnerJoin, RightJoin, Parent } 9 | } 10 | -------------------------------------------------------------------------------- /FreeSql/Internal/Model/TableInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Reflection; 4 | 5 | namespace FreeSql.Internal.Model { 6 | class TableInfo { 7 | public Type Type { get; set; } 8 | public Type TypeLazy { get; set; } 9 | public MethodInfo TypeLazySetOrm { get; set; } 10 | public Dictionary Properties { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); 11 | public Dictionary Columns { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); 12 | public Dictionary ColumnsByCs { get; set; } = new Dictionary(StringComparer.CurrentCultureIgnoreCase); 13 | public ColumnInfo[] Primarys { get; set; } 14 | public string CsName { get; set; } 15 | public string DbName { get; set; } 16 | public string DbOldName { get; set; } 17 | public string SelectFilter { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /FreeSql/MySql/Curd/MySqlDelete.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FreeSql.MySql.Curd { 8 | 9 | class MySqlDelete : Internal.CommonProvider.DeleteProvider where T1 : class { 10 | public MySqlDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 11 | : base(orm, commonUtils, commonExpression, dywhere) { 12 | } 13 | 14 | public override List ExecuteDeleted() { 15 | var sql = this.ToSql(); 16 | if (string.IsNullOrEmpty(sql)) return new List(); 17 | 18 | var sb = new StringBuilder(); 19 | sb.Append(sql).Append(" RETURNING "); 20 | 21 | var colidx = 0; 22 | foreach (var col in _table.Columns.Values) { 23 | if (colidx > 0) sb.Append(", "); 24 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 25 | ++colidx; 26 | } 27 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.ToArray()); 28 | } 29 | async public override Task> ExecuteDeletedAsync() { 30 | var sql = this.ToSql(); 31 | if (string.IsNullOrEmpty(sql)) return new List(); 32 | 33 | var sb = new StringBuilder(); 34 | sb.Append(sql).Append(" RETURNING "); 35 | 36 | var colidx = 0; 37 | foreach (var col in _table.Columns.Values) { 38 | if (colidx > 0) sb.Append(", "); 39 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 40 | ++colidx; 41 | } 42 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.ToArray()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /FreeSql/MySql/Curd/MySqlInsert.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FreeSql.MySql.Curd { 8 | 9 | class MySqlInsert : Internal.CommonProvider.InsertProvider where T1 : class { 10 | public MySqlInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) 11 | : base(orm, commonUtils, commonExpression) { 12 | } 13 | 14 | public override long ExecuteIdentity() { 15 | var sql = this.ToSql(); 16 | if (string.IsNullOrEmpty(sql)) return 0; 17 | 18 | return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; 19 | } 20 | async public override Task ExecuteIdentityAsync() { 21 | var sql = this.ToSql(); 22 | if (string.IsNullOrEmpty(sql)) return 0; 23 | 24 | return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, "; SELECT LAST_INSERT_ID();"), _params)), out var trylng) ? trylng : 0; 25 | } 26 | 27 | public override List ExecuteInserted() { 28 | var sql = this.ToSql(); 29 | if (string.IsNullOrEmpty(sql)) return new List(); 30 | 31 | var sb = new StringBuilder(); 32 | sb.Append(sql).Append(" RETURNING "); 33 | 34 | var colidx = 0; 35 | foreach (var col in _table.Columns.Values) { 36 | if (colidx > 0) sb.Append(", "); 37 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 38 | ++colidx; 39 | } 40 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params); 41 | } 42 | async public override Task> ExecuteInsertedAsync() { 43 | var sql = this.ToSql(); 44 | if (string.IsNullOrEmpty(sql)) return new List(); 45 | 46 | var sb = new StringBuilder(); 47 | sb.Append(sql).Append(" RETURNING "); 48 | 49 | var colidx = 0; 50 | foreach (var col in _table.Columns.Values) { 51 | if (colidx > 0) sb.Append(", "); 52 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 53 | ++colidx; 54 | } 55 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /FreeSql/MySql/Curd/MySqlUpdate.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.Model; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace FreeSql.MySql.Curd { 10 | 11 | class MySqlUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { 12 | 13 | public MySqlUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 14 | : base(orm, commonUtils, commonExpression, dywhere) { 15 | } 16 | 17 | public override List ExecuteUpdated() { 18 | var sql = this.ToSql(); 19 | if (string.IsNullOrEmpty(sql)) return new List(); 20 | 21 | var sb = new StringBuilder(); 22 | sb.Append(sql).Append(" RETURNING "); 23 | 24 | var colidx = 0; 25 | foreach (var col in _table.Columns.Values) { 26 | if (colidx > 0) sb.Append(", "); 27 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 28 | ++colidx; 29 | } 30 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); 31 | } 32 | async public override Task> ExecuteUpdatedAsync() { 33 | var sql = this.ToSql(); 34 | if (string.IsNullOrEmpty(sql)) return new List(); 35 | 36 | var sb = new StringBuilder(); 37 | sb.Append(sql).Append(" RETURNING "); 38 | 39 | var colidx = 0; 40 | foreach (var col in _table.Columns.Values) { 41 | if (colidx > 0) sb.Append(", "); 42 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 43 | ++colidx; 44 | } 45 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); 46 | } 47 | 48 | protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { 49 | if (_table.Primarys.Length == 1) { 50 | caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); 51 | return; 52 | } 53 | caseWhen.Append("CONCAT("); 54 | var pkidx = 0; 55 | foreach (var pk in _table.Primarys) { 56 | if (pkidx > 0) caseWhen.Append(", "); 57 | caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); 58 | ++pkidx; 59 | } 60 | caseWhen.Append(")"); 61 | } 62 | 63 | protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { 64 | if (_table.Primarys.Length == 1) { 65 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null)); 66 | return; 67 | } 68 | sb.Append("CONCAT("); 69 | var pkidx = 0; 70 | foreach (var pk in _table.Primarys) { 71 | if (pkidx > 0) sb.Append(", "); 72 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null)); 73 | ++pkidx; 74 | } 75 | sb.Append(")"); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FreeSql/MySql/MySqlAdo/MySqlAdo.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using Microsoft.Extensions.Logging; 3 | using MySql.Data.MySqlClient; 4 | using SafeObjectPool; 5 | using System; 6 | using System.Collections; 7 | using System.Data.Common; 8 | using System.Text; 9 | using System.Threading; 10 | 11 | namespace FreeSql.MySql { 12 | class MySqlAdo : FreeSql.Internal.CommonProvider.AdoProvider { 13 | CommonUtils _util; 14 | 15 | public MySqlAdo() : base(null, null) { } 16 | public MySqlAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log) { 17 | this._util = util; 18 | MasterPool = new MySqlConnectionPool("主库", masterConnectionString, null, null); 19 | if (slaveConnectionStrings != null) { 20 | foreach (var slaveConnectionString in slaveConnectionStrings) { 21 | var slavePool = new MySqlConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); 22 | SlavePools.Add(slavePool); 23 | } 24 | } 25 | } 26 | static DateTime dt1970 = new DateTime(1970, 1, 1); 27 | public override object AddslashesProcessParam(object param) { 28 | if (param == null) return "NULL"; 29 | if (param is bool || param is bool?) 30 | return (bool)param ? 1 : 0; 31 | else if (param is string) 32 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 33 | else if (param is Enum) 34 | return ((Enum)param).ToInt64(); 35 | else if (decimal.TryParse(string.Concat(param), out var trydec)) 36 | return param; 37 | else if (param is DateTime) 38 | return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'"); 39 | else if (param is DateTime?) 40 | return string.Concat("'", (param as DateTime?).Value.ToString("yyyy-MM-dd HH:mm:ss"), "'"); 41 | else if (param is TimeSpan) 42 | return ((TimeSpan)param).Ticks / 10; 43 | else if (param is TimeSpan?) 44 | return (param as TimeSpan?).Value.Ticks / 10; 45 | else if (param is MygisGeometry) 46 | return (param as MygisGeometry).AsText(); 47 | else if (param is IEnumerable) { 48 | var sb = new StringBuilder(); 49 | var ie = param as IEnumerable; 50 | foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z)); 51 | return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); 52 | } 53 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 54 | //if (param is string) return string.Concat('N', nparms[a]); 55 | } 56 | 57 | protected override DbCommand CreateCommand() { 58 | return new MySqlCommand(); 59 | } 60 | 61 | protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { 62 | (pool as MySqlConnectionPool).Return(conn, ex); 63 | } 64 | 65 | protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /FreeSql/MySql/MySqlAdo/MygisTypesExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Reflection; 7 | using System.Text; 8 | 9 | public static partial class MygisTypesExtensions { 10 | /// 11 | /// 测量两个经纬度的距离,返回单位:米 12 | /// 13 | /// 经纬坐标1 14 | /// 经纬坐标2 15 | /// 返回距离(单位:米) 16 | public static double Distance(this MygisPoint that, MygisPoint point) { 17 | double radLat1 = (double)(that.Y) * Math.PI / 180d; 18 | double radLng1 = (double)(that.X) * Math.PI / 180d; 19 | double radLat2 = (double)(point.Y) * Math.PI / 180d; 20 | double radLng2 = (double)(point.X) * Math.PI / 180d; 21 | return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137; 22 | } 23 | } -------------------------------------------------------------------------------- /FreeSql/MySql/MySqlProvider.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.CommonProvider; 3 | using FreeSql.MySql.Curd; 4 | using Microsoft.Extensions.Caching.Distributed; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Data.Common; 10 | 11 | namespace FreeSql.MySql { 12 | 13 | class MySqlProvider : IFreeSql { 14 | 15 | public ISelect Select() where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 16 | public ISelect Select(object dywhere) where T1 : class => new MySqlSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 17 | public IInsert Insert() where T1 : class => new MySqlInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); 18 | public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); 19 | public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); 20 | public IUpdate Update() where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 21 | public IUpdate Update(object dywhere) where T1 : class => new MySqlUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 22 | public IDelete Delete() where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 23 | public IDelete Delete(object dywhere) where T1 : class => new MySqlDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 24 | 25 | public IAdo Ado { get; } 26 | public ICache Cache { get; } 27 | public ICodeFirst CodeFirst { get; } 28 | public IDbFirst DbFirst { get; } 29 | public MySqlProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { 30 | if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.MySql"); 31 | 32 | this.InternalCommonUtils = new MySqlUtils(this); 33 | this.InternalCommonExpression = new MySqlExpression(this.InternalCommonUtils); 34 | 35 | this.Cache = new CacheProvider(cache, log); 36 | this.Ado = new MySqlAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString); 37 | 38 | this.DbFirst = new MySqlDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 39 | this.CodeFirst = new MySqlCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 40 | } 41 | 42 | internal CommonUtils InternalCommonUtils { get; } 43 | internal CommonExpression InternalCommonExpression { get; } 44 | 45 | public void Transaction(Action handler) => Ado.Transaction(handler); 46 | 47 | public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /FreeSql/MySql/MySqlUtils.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.Model; 3 | using MySql.Data.MySqlClient; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Data.Common; 7 | 8 | namespace FreeSql.MySql { 9 | 10 | class MySqlUtils : CommonUtils { 11 | public MySqlUtils(IFreeSql orm) : base(orm) { 12 | } 13 | 14 | internal override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { 15 | if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; 16 | else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower(); 17 | var ret = new MySqlParameter { ParameterName = $"?{parameterName}", Value = value }; 18 | var tp = _orm.CodeFirst.GetDbInfo(type)?.type; 19 | if (tp != null) { 20 | if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { 21 | ret.MySqlDbType = MySqlDbType.Text; 22 | if (value != null) ret.Value = (value as MygisGeometry).AsText(); 23 | } else 24 | ret.MySqlDbType = (MySqlDbType)tp.Value; 25 | } 26 | _params?.Add(ret); 27 | return ret; 28 | } 29 | 30 | internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) => 31 | Utils.GetDbParamtersByObject(sql, obj, "?", (name, type, value) => { 32 | var ret = new MySqlParameter { ParameterName = $"?{name}", Value = value }; 33 | var tp = _orm.CodeFirst.GetDbInfo(type)?.type; 34 | if (tp != null) { 35 | if ((MySqlDbType)tp.Value == MySqlDbType.Geometry) { 36 | ret.MySqlDbType = MySqlDbType.Text; 37 | if (value != null) ret.Value = (value as MygisGeometry).AsText(); 38 | } else 39 | ret.MySqlDbType = (MySqlDbType)tp.Value; 40 | } 41 | return ret; 42 | }); 43 | 44 | internal override string FormatSql(string sql, params object[] args) => sql?.FormatMySql(args); 45 | internal override string QuoteSqlName(string name) => $"`{name.Trim('`').Replace(".", "`.`")}`"; 46 | internal override string QuoteParamterName(string name) => $"?{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; 47 | internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; 48 | internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"concat({left}, {right})"; 49 | internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; 50 | internal override string QuoteWriteParamter(Type type, string paramterName) { 51 | switch (type.FullName) { 52 | case "MygisPoint": 53 | case "MygisLineString": 54 | case "MygisPolygon": 55 | case "MygisMultiPoint": 56 | case "MygisMultiLineString": 57 | case "MygisMultiPolygon": return $"ST_GeomFromText({paramterName})"; 58 | } 59 | return paramterName; 60 | } 61 | 62 | internal override string QuoteReadColumn(Type type, string columnName) { 63 | switch (type.FullName) { 64 | case "MygisPoint": 65 | case "MygisLineString": 66 | case "MygisPolygon": 67 | case "MygisMultiPoint": 68 | case "MygisMultiLineString": 69 | case "MygisMultiPolygon": return $"AsText({columnName})"; 70 | } 71 | return columnName; 72 | } 73 | internal override string DbName => "MySql"; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /FreeSql/Oracle/Curd/OracleDelete.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace FreeSql.Oracle.Curd { 9 | 10 | class OracleDelete : Internal.CommonProvider.DeleteProvider where T1 : class { 11 | public OracleDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 12 | : base(orm, commonUtils, commonExpression, dywhere) { 13 | } 14 | 15 | public override List ExecuteDeleted() { 16 | throw new NotImplementedException(); 17 | } 18 | public override Task> ExecuteDeletedAsync() { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FreeSql/Oracle/Curd/OracleUpdate.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.Model; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace FreeSql.Oracle.Curd { 11 | 12 | class OracleUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { 13 | 14 | public OracleUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 15 | : base(orm, commonUtils, commonExpression, dywhere) { 16 | } 17 | 18 | public override List ExecuteUpdated() { 19 | throw new NotImplementedException(); 20 | } 21 | public override Task> ExecuteUpdatedAsync() { 22 | throw new NotImplementedException(); 23 | } 24 | 25 | protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { 26 | if (_table.Primarys.Length == 1) { 27 | caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); 28 | return; 29 | } 30 | caseWhen.Append("("); 31 | var pkidx = 0; 32 | foreach (var pk in _table.Primarys) { 33 | if (pkidx > 0) caseWhen.Append(" || "); 34 | caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); 35 | ++pkidx; 36 | } 37 | caseWhen.Append(")"); 38 | } 39 | 40 | protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { 41 | if (_table.Primarys.Length == 1) { 42 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null)); 43 | return; 44 | } 45 | sb.Append("("); 46 | var pkidx = 0; 47 | foreach (var pk in _table.Primarys) { 48 | if (pkidx > 0) sb.Append(" || "); 49 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null)); 50 | ++pkidx; 51 | } 52 | sb.Append(")"); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /FreeSql/Oracle/OracleAdo/OracleAdo.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using Microsoft.Extensions.Logging; 3 | using Oracle.ManagedDataAccess.Client; 4 | using SafeObjectPool; 5 | using System; 6 | using System.Collections; 7 | using System.Data.Common; 8 | using System.Text; 9 | using System.Threading; 10 | 11 | namespace FreeSql.Oracle { 12 | class OracleAdo : FreeSql.Internal.CommonProvider.AdoProvider { 13 | CommonUtils _util; 14 | 15 | public OracleAdo() : base(null, null) { } 16 | public OracleAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log) { 17 | this._util = util; 18 | MasterPool = new OracleConnectionPool("主库", masterConnectionString, null, null); 19 | if (slaveConnectionStrings != null) { 20 | foreach (var slaveConnectionString in slaveConnectionStrings) { 21 | var slavePool = new OracleConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); 22 | SlavePools.Add(slavePool); 23 | } 24 | } 25 | } 26 | static DateTime dt1970 = new DateTime(1970, 1, 1); 27 | public override object AddslashesProcessParam(object param) { 28 | if (param == null) return "NULL"; 29 | if (param is bool || param is bool?) 30 | return (bool)param ? 1 : 0; 31 | else if (param is string) 32 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 33 | else if (param is Enum) 34 | return ((Enum)param).ToInt64(); 35 | else if (decimal.TryParse(string.Concat(param), out var trydec)) 36 | return param; 37 | else if (param is DateTime) 38 | return string.Concat("to_timestamp('", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6)"); 39 | else if (param is DateTime?) 40 | return string.Concat("to_timestamp('", (param as DateTime?).Value.ToString("yyyy-MM-dd HH:mm:ss.ffffff"), "','YYYY-MM-DD HH24:MI:SS.FF6)"); 41 | else if (param is TimeSpan) 42 | return $"numtodsinterval({((TimeSpan)param).Ticks * 1.0 / 10000000},'second')"; 43 | else if (param is TimeSpan?) 44 | return $"numtodsinterval({(param as TimeSpan?).Value.Ticks * 1.0 / 10000000},'second')"; 45 | else if (param is IEnumerable) { 46 | var sb = new StringBuilder(); 47 | var ie = param as IEnumerable; 48 | foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z)); 49 | return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); 50 | } 51 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 52 | //if (param is string) return string.Concat('N', nparms[a]); 53 | } 54 | 55 | protected override DbCommand CreateCommand() { 56 | return new OracleCommand(); 57 | } 58 | 59 | protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { 60 | (pool as OracleConnectionPool).Return(conn, ex); 61 | } 62 | 63 | protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /FreeSql/Oracle/OracleProvider.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.CommonProvider; 3 | using FreeSql.Oracle.Curd; 4 | using Microsoft.Extensions.Caching.Distributed; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Data.Common; 10 | 11 | namespace FreeSql.Oracle { 12 | 13 | class OracleProvider : IFreeSql { 14 | 15 | public ISelect Select() where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 16 | public ISelect Select(object dywhere) where T1 : class => new OracleSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 17 | public IInsert Insert() where T1 : class => new OracleInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); 18 | public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); 19 | public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); 20 | public IUpdate Update() where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 21 | public IUpdate Update(object dywhere) where T1 : class => new OracleUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 22 | public IDelete Delete() where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 23 | public IDelete Delete(object dywhere) where T1 : class => new OracleDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 24 | 25 | public IAdo Ado { get; } 26 | public ICache Cache { get; } 27 | public ICodeFirst CodeFirst { get; } 28 | public IDbFirst DbFirst { get { throw new NotImplementedException(); } } 29 | public OracleProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { 30 | if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.Oracle"); 31 | 32 | this.InternalCommonUtils = new OracleUtils(this); 33 | this.InternalCommonExpression = new OracleExpression(this.InternalCommonUtils); 34 | 35 | this.Cache = new CacheProvider(cache, log); 36 | this.Ado = new OracleAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString); 37 | 38 | this.CodeFirst = new OracleCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 39 | } 40 | 41 | internal CommonUtils InternalCommonUtils { get; } 42 | internal CommonExpression InternalCommonExpression { get; } 43 | 44 | public void Transaction(Action handler) => Ado.Transaction(handler); 45 | 46 | public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /FreeSql/Oracle/OracleUtils.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.Model; 3 | using Oracle.ManagedDataAccess.Client; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Data.Common; 7 | 8 | namespace FreeSql.Oracle { 9 | 10 | class OracleUtils : CommonUtils { 11 | public OracleUtils(IFreeSql orm) : base(orm) { 12 | } 13 | 14 | internal override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { 15 | if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; 16 | else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower(); 17 | var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; 18 | if (dbtype == OracleDbType.Boolean) { 19 | if (value == null) value = null; 20 | else value = (bool)value == true ? 1 : 0; 21 | dbtype = OracleDbType.Int16; 22 | } 23 | var ret = new OracleParameter { ParameterName = $":{parameterName}", OracleDbType = dbtype, Value = value }; 24 | _params?.Add(ret); 25 | return ret; 26 | } 27 | 28 | internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) => 29 | Utils.GetDbParamtersByObject(sql, obj, ":", (name, type, value) => { 30 | var dbtype = (OracleDbType)_orm.CodeFirst.GetDbInfo(type)?.type; 31 | if (dbtype == OracleDbType.Boolean) { 32 | if (value == null) value = null; 33 | else value = (bool)value == true ? 1 : 0; 34 | dbtype = OracleDbType.Int16; 35 | } 36 | var ret = new OracleParameter { ParameterName = $":{name}", OracleDbType = dbtype, Value = value }; 37 | return ret; 38 | }); 39 | 40 | internal override string FormatSql(string sql, params object[] args) => sql?.FormatOracleSQL(args); 41 | internal override string QuoteSqlName(string name) => $"\"{name.Trim('"').Replace(".", "\".\"")}\""; 42 | internal override string QuoteParamterName(string name) => $":{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; 43 | internal override string IsNull(string sql, object value) => $"nvl({sql}, {value})"; 44 | internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}"; 45 | internal override string Mod(string left, string right, Type leftType, Type rightType) => $"mod({left}, {right})"; 46 | 47 | internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName; 48 | internal override string QuoteReadColumn(Type type, string columnName) => columnName; 49 | internal override string DbName => "Oracle"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /FreeSql/PostgreSQL/Curd/PostgreSQLDelete.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace FreeSql.PostgreSQL.Curd { 8 | 9 | class PostgreSQLDelete : Internal.CommonProvider.DeleteProvider where T1 : class { 10 | public PostgreSQLDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 11 | : base(orm, commonUtils, commonExpression, dywhere) { 12 | } 13 | 14 | public override List ExecuteDeleted() { 15 | var sql = this.ToSql(); 16 | if (string.IsNullOrEmpty(sql)) return new List(); 17 | 18 | var sb = new StringBuilder(); 19 | sb.Append(sql).Append(" RETURNING "); 20 | 21 | var colidx = 0; 22 | foreach (var col in _table.Columns.Values) { 23 | if (colidx > 0) sb.Append(", "); 24 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 25 | ++colidx; 26 | } 27 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.ToArray()); 28 | } 29 | async public override Task> ExecuteDeletedAsync() { 30 | var sql = this.ToSql(); 31 | if (string.IsNullOrEmpty(sql)) return new List(); 32 | 33 | var sb = new StringBuilder(); 34 | sb.Append(sql).Append(" RETURNING "); 35 | 36 | var colidx = 0; 37 | foreach (var col in _table.Columns.Values) { 38 | if (colidx > 0) sb.Append(", "); 39 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 40 | ++colidx; 41 | } 42 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.ToArray()); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /FreeSql/PostgreSQL/Curd/PostgreSQLInsert.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace FreeSql.PostgreSQL.Curd { 9 | 10 | class PostgreSQLInsert : Internal.CommonProvider.InsertProvider where T1 : class { 11 | public PostgreSQLInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) 12 | : base(orm, commonUtils, commonExpression) { 13 | } 14 | 15 | public override long ExecuteIdentity() { 16 | var sql = this.ToSql(); 17 | if (string.IsNullOrEmpty(sql)) return 0; 18 | 19 | var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); 20 | if (identCols.Any() == false) { 21 | _orm.Ado.ExecuteNonQuery(CommandType.Text, sql, _params); 22 | return 0; 23 | } 24 | return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; 25 | } 26 | async public override Task ExecuteIdentityAsync() { 27 | var sql = this.ToSql(); 28 | if (string.IsNullOrEmpty(sql)) return 0; 29 | 30 | var identCols = _table.Columns.Where(a => a.Value.Attribute.IsIdentity == true); 31 | if (identCols.Any() == false) { 32 | await _orm.Ado.ExecuteNonQueryAsync(CommandType.Text, sql, _params); 33 | return 0; 34 | } 35 | return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, " RETURNING ", _commonUtils.QuoteSqlName(identCols.First().Value.Attribute.Name)), _params)), out var trylng) ? trylng : 0; 36 | } 37 | 38 | public override List ExecuteInserted() { 39 | var sql = this.ToSql(); 40 | if (string.IsNullOrEmpty(sql)) return new List(); 41 | 42 | var sb = new StringBuilder(); 43 | sb.Append(sql).Append(" RETURNING "); 44 | 45 | var colidx = 0; 46 | foreach (var col in _table.Columns.Values) { 47 | if (colidx > 0) sb.Append(", "); 48 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 49 | ++colidx; 50 | } 51 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params); 52 | } 53 | async public override Task> ExecuteInsertedAsync() { 54 | var sql = this.ToSql(); 55 | if (string.IsNullOrEmpty(sql)) return new List(); 56 | 57 | var sb = new StringBuilder(); 58 | sb.Append(sql).Append(" RETURNING "); 59 | 60 | var colidx = 0; 61 | foreach (var col in _table.Columns.Values) { 62 | if (colidx > 0) sb.Append(", "); 63 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 64 | ++colidx; 65 | } 66 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /FreeSql/PostgreSQL/Curd/PostgreSQLUpdate.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.Model; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace FreeSql.PostgreSQL.Curd { 10 | 11 | class PostgreSQLUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { 12 | 13 | public PostgreSQLUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 14 | : base(orm, commonUtils, commonExpression, dywhere) { 15 | } 16 | 17 | public override List ExecuteUpdated() { 18 | var sql = this.ToSql(); 19 | if (string.IsNullOrEmpty(sql)) return new List(); 20 | 21 | var sb = new StringBuilder(); 22 | sb.Append(sql).Append(" RETURNING "); 23 | 24 | var colidx = 0; 25 | foreach (var col in _table.Columns.Values) { 26 | if (colidx > 0) sb.Append(", "); 27 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 28 | ++colidx; 29 | } 30 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); 31 | } 32 | async public override Task> ExecuteUpdatedAsync() { 33 | var sql = this.ToSql(); 34 | if (string.IsNullOrEmpty(sql)) return new List(); 35 | 36 | var sb = new StringBuilder(); 37 | sb.Append(sql).Append(" RETURNING "); 38 | 39 | var colidx = 0; 40 | foreach (var col in _table.Columns.Values) { 41 | if (colidx > 0) sb.Append(", "); 42 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 43 | ++colidx; 44 | } 45 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.Concat(_paramsSource).ToArray()); 46 | } 47 | 48 | protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { 49 | if (_table.Primarys.Length == 1) { 50 | caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); 51 | return; 52 | } 53 | caseWhen.Append("("); 54 | var pkidx = 0; 55 | foreach (var pk in _table.Primarys) { 56 | if (pkidx > 0) caseWhen.Append(" || "); 57 | caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name))).Append("::varchar"); 58 | ++pkidx; 59 | } 60 | caseWhen.Append(")"); 61 | } 62 | 63 | protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { 64 | if (_table.Primarys.Length == 1) { 65 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null)); 66 | return; 67 | } 68 | sb.Append("("); 69 | var pkidx = 0; 70 | foreach (var pk in _table.Primarys) { 71 | if (pkidx > 0) sb.Append(" || "); 72 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null)).Append("::varchar"); 73 | ++pkidx; 74 | } 75 | sb.Append(")"); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FreeSql/PostgreSQL/PostgreSQLAdo/PostgreSQLTypesExtensions.cs: -------------------------------------------------------------------------------- 1 | using Npgsql.LegacyPostgis; 2 | using NpgsqlTypes; 3 | using System; 4 | using System.Collections; 5 | 6 | public static partial class PostgreSQLTypesExtensions { 7 | /// 8 | /// 测量两个经纬度的距离,返回单位:米 9 | /// 10 | /// 经纬坐标1 11 | /// 经纬坐标2 12 | /// 返回距离(单位:米) 13 | public static double Distance(this NpgsqlPoint that, NpgsqlPoint point) { 14 | double radLat1 = (double)(that.Y) * Math.PI / 180d; 15 | double radLng1 = (double)(that.X) * Math.PI / 180d; 16 | double radLat2 = (double)(point.Y) * Math.PI / 180d; 17 | double radLng2 = (double)(point.X) * Math.PI / 180d; 18 | return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137; 19 | } 20 | 21 | /// 22 | /// 测量两个经纬度的距离,返回单位:米 23 | /// 24 | /// 经纬坐标1 25 | /// 经纬坐标2 26 | /// 返回距离(单位:米) 27 | public static double Distance(this PostgisPoint that, PostgisPoint point) { 28 | double radLat1 = (double)(that.Y) * Math.PI / 180d; 29 | double radLng1 = (double)(that.X) * Math.PI / 180d; 30 | double radLat2 = (double)(point.Y) * Math.PI / 180d; 31 | double radLng2 = (double)(point.X) * Math.PI / 180d; 32 | return 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin((radLat1 - radLat2) / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin((radLng1 - radLng2) / 2), 2))) * 6378137; 33 | } 34 | 35 | public static string To1010(this BitArray ba) { 36 | char[] ret = new char[ba.Length]; 37 | for (int a = 0; a < ba.Length; a++) ret[a] = ba[a] ? '1' : '0'; 38 | return new string(ret); 39 | } 40 | 41 | /// 42 | /// 将 1010101010 这样的二进制字符串转换成 BitArray 43 | /// 44 | /// 1010101010 45 | /// 46 | public static BitArray ToBitArray(this string _1010Str) { 47 | if (_1010Str == null) return null; 48 | BitArray ret = new BitArray(_1010Str.Length); 49 | for (int a = 0; a < _1010Str.Length; a++) ret[a] = _1010Str[a] == '1'; 50 | return ret; 51 | } 52 | 53 | public static NpgsqlRange ToNpgsqlRange(this string that) { 54 | var s = that; 55 | if (string.IsNullOrEmpty(s) || s == "empty") return NpgsqlRange.Empty; 56 | string s1 = s.Trim('(', ')', '[', ']'); 57 | string[] ss = s1.Split(new char[] { ',' }, 2); 58 | if (ss.Length != 2) return NpgsqlRange.Empty; 59 | T t1 = default(T); 60 | T t2 = default(T); 61 | if (!string.IsNullOrEmpty(ss[0])) t1 = (T)Convert.ChangeType(ss[0], typeof(T)); 62 | if (!string.IsNullOrEmpty(ss[1])) t2 = (T)Convert.ChangeType(ss[1], typeof(T)); 63 | return new NpgsqlRange(t1, s[0] == '[', s[0] == '(', t2, s[s.Length - 1] == ']', s[s.Length - 1] == ')'); 64 | } 65 | } -------------------------------------------------------------------------------- /FreeSql/PostgreSQL/PostgreSQLProvider.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.CommonProvider; 3 | using FreeSql.PostgreSQL.Curd; 4 | using Microsoft.Extensions.Caching.Distributed; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Data.Common; 10 | 11 | namespace FreeSql.PostgreSQL { 12 | 13 | class PostgreSQLProvider : IFreeSql { 14 | 15 | public ISelect Select() where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 16 | public ISelect Select(object dywhere) where T1 : class => new PostgreSQLSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 17 | public IInsert Insert() where T1 : class => new PostgreSQLInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); 18 | public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); 19 | public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); 20 | public IUpdate Update() where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 21 | public IUpdate Update(object dywhere) where T1 : class => new PostgreSQLUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 22 | public IDelete Delete() where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 23 | public IDelete Delete(object dywhere) where T1 : class => new PostgreSQLDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 24 | 25 | public IAdo Ado { get; } 26 | public ICache Cache { get; } 27 | public ICodeFirst CodeFirst { get; } 28 | public IDbFirst DbFirst { get; } 29 | public PostgreSQLProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { 30 | if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.PostgreSQL"); 31 | 32 | this.InternalCommonUtils = new PostgreSQLUtils(this); 33 | this.InternalCommonExpression = new PostgreSQLExpression(this.InternalCommonUtils); 34 | 35 | this.Cache = new CacheProvider(cache, log); 36 | this.Ado = new PostgreSQLAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString); 37 | 38 | this.DbFirst = new PostgreSQLDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 39 | this.CodeFirst = new PostgreSQLCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 40 | } 41 | 42 | internal CommonUtils InternalCommonUtils { get; } 43 | internal CommonExpression InternalCommonExpression { get; } 44 | 45 | public void Transaction(Action handler) => Ado.Transaction(handler); 46 | 47 | public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /FreeSql/SqlServer/Curd/SqlServerDelete.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace FreeSql.SqlServer.Curd { 9 | 10 | class SqlServerDelete : Internal.CommonProvider.DeleteProvider where T1 : class { 11 | public SqlServerDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 12 | : base(orm, commonUtils, commonExpression, dywhere) { 13 | } 14 | 15 | public override List ExecuteDeleted() { 16 | var sql = this.ToSql(); 17 | if (string.IsNullOrEmpty(sql)) return new List(); 18 | 19 | var sb = new StringBuilder(); 20 | sb.Append(" OUTPUT "); 21 | var colidx = 0; 22 | foreach (var col in _table.Columns.Values) { 23 | if (colidx > 0) sb.Append(", "); 24 | sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 25 | ++colidx; 26 | } 27 | 28 | var validx = sql.IndexOf(" WHERE "); 29 | if (validx == -1) throw new ArgumentException("找不到 WHERE "); 30 | sb.Insert(0, sql.Substring(0, validx)); 31 | sb.Append(sql.Substring(validx)); 32 | 33 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params.ToArray()); 34 | } 35 | async public override Task> ExecuteDeletedAsync() { 36 | var sql = this.ToSql(); 37 | if (string.IsNullOrEmpty(sql)) return new List(); 38 | 39 | var sb = new StringBuilder(); 40 | sb.Append(" OUTPUT "); 41 | var colidx = 0; 42 | foreach (var col in _table.Columns.Values) { 43 | if (colidx > 0) sb.Append(", "); 44 | sb.Append("DELETED.").Append(_commonUtils.QuoteReadColumn(col.CsType, _commonUtils.QuoteSqlName(col.Attribute.Name))).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 45 | ++colidx; 46 | } 47 | 48 | var validx = sql.IndexOf(" WHERE "); 49 | if (validx == -1) throw new ArgumentException("找不到 WHERE "); 50 | sb.Insert(0, sql.Substring(0, validx)); 51 | sb.Append(sql.Substring(validx)); 52 | 53 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params.ToArray()); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /FreeSql/SqlServer/Curd/SqlServerInsert.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace FreeSql.SqlServer.Curd { 9 | 10 | class SqlServerInsert : Internal.CommonProvider.InsertProvider where T1 : class { 11 | public SqlServerInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) 12 | : base(orm, commonUtils, commonExpression) { 13 | } 14 | 15 | public override long ExecuteIdentity() { 16 | var sql = this.ToSql(); 17 | if (string.IsNullOrEmpty(sql)) return 0; 18 | 19 | return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; 20 | } 21 | async public override Task ExecuteIdentityAsync() { 22 | var sql = this.ToSql(); 23 | if (string.IsNullOrEmpty(sql)) return 0; 24 | 25 | return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, "; SELECT SCOPE_IDENTITY();"), _params)), out var trylng) ? trylng : 0; 26 | } 27 | 28 | public override List ExecuteInserted() { 29 | var sql = this.ToSql(); 30 | if (string.IsNullOrEmpty(sql)) return new List(); 31 | 32 | var sb = new StringBuilder(); 33 | sb.Append(" OUTPUT "); 34 | var colidx = 0; 35 | foreach (var col in _table.Columns.Values) { 36 | if (colidx > 0) sb.Append(", "); 37 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 38 | ++colidx; 39 | } 40 | 41 | var validx = sql.IndexOf(") VALUES"); 42 | if (validx == -1) throw new ArgumentException("找不到 VALUES"); 43 | sb.Insert(0, sql.Substring(0, validx + 1)); 44 | sb.Append(sql.Substring(validx + 1)); 45 | 46 | return _orm.Ado.Query(CommandType.Text, sb.ToString(), _params); 47 | } 48 | async public override Task> ExecuteInsertedAsync() { 49 | var sql = this.ToSql(); 50 | if (string.IsNullOrEmpty(sql)) return new List(); 51 | 52 | var sb = new StringBuilder(); 53 | sb.Append(" OUTPUT "); 54 | var colidx = 0; 55 | foreach (var col in _table.Columns.Values) { 56 | if (colidx > 0) sb.Append(", "); 57 | sb.Append(_commonUtils.QuoteReadColumn(col.CsType, $"INSERTED.{_commonUtils.QuoteSqlName(col.Attribute.Name)}")).Append(" as ").Append(_commonUtils.QuoteSqlName(col.CsName)); 58 | ++colidx; 59 | } 60 | 61 | var validx = sql.IndexOf(") VALUES"); 62 | if (validx == -1) throw new ArgumentException("找不到 VALUES"); 63 | sb.Insert(0, sql.Substring(0, validx + 1)); 64 | sb.Append(sql.Substring(validx + 1)); 65 | 66 | return await _orm.Ado.QueryAsync(CommandType.Text, sb.ToString(), _params); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /FreeSql/SqlServer/SqlServerAdo/SqlServerAdo.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using Microsoft.Extensions.Logging; 3 | using SafeObjectPool; 4 | using System; 5 | using System.Collections; 6 | using System.Data.Common; 7 | using System.Data.SqlClient; 8 | using System.Text; 9 | using System.Threading; 10 | 11 | namespace FreeSql.SqlServer { 12 | class SqlServerAdo : FreeSql.Internal.CommonProvider.AdoProvider { 13 | CommonUtils _util; 14 | 15 | public SqlServerAdo() : base(null, null) { } 16 | public SqlServerAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log) { 17 | this._util = util; 18 | MasterPool = new SqlServerConnectionPool("主库", masterConnectionString, null, null); 19 | if (slaveConnectionStrings != null) { 20 | foreach (var slaveConnectionString in slaveConnectionStrings) { 21 | var slavePool = new SqlServerConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); 22 | SlavePools.Add(slavePool); 23 | } 24 | } 25 | } 26 | static DateTime dt1970 = new DateTime(1970, 1, 1); 27 | public override object AddslashesProcessParam(object param) { 28 | if (param == null) return "NULL"; 29 | if (param is bool || param is bool?) 30 | return (bool)param ? 1 : 0; 31 | else if (param is string || param is Enum) 32 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 33 | else if (decimal.TryParse(string.Concat(param), out var trydec)) 34 | return param; 35 | else if (param is DateTime) 36 | return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); 37 | else if (param is DateTime?) 38 | return string.Concat("'", (param as DateTime?).Value.ToString("yyyy-MM-dd HH:mm:ss.fff"), "'"); 39 | else if (param is TimeSpan) 40 | return ((TimeSpan)param).TotalSeconds; 41 | else if (param is TimeSpan?) 42 | return (param as TimeSpan?).Value.TotalSeconds; 43 | else if (param is IEnumerable) { 44 | var sb = new StringBuilder(); 45 | var ie = param as IEnumerable; 46 | foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z)); 47 | return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); 48 | } else { 49 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 50 | //if (param is string) return string.Concat('N', nparms[a]); 51 | } 52 | } 53 | 54 | protected override DbCommand CreateCommand() { 55 | return new SqlCommand(); 56 | } 57 | 58 | protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { 59 | (pool as SqlServerConnectionPool).Return(conn, ex); 60 | } 61 | 62 | protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); 63 | } 64 | } -------------------------------------------------------------------------------- /FreeSql/SqlServer/SqlServerProvider.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.CommonProvider; 3 | using FreeSql.SqlServer.Curd; 4 | using Microsoft.Extensions.Caching.Distributed; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using System; 8 | using System.Collections.Generic; 9 | 10 | namespace FreeSql.SqlServer { 11 | 12 | class SqlServerProvider : IFreeSql { 13 | 14 | public ISelect Select() where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 15 | public ISelect Select(object dywhere) where T1 : class => new SqlServerSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 16 | public IInsert Insert() where T1 : class => new SqlServerInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); 17 | public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); 18 | public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); 19 | public IUpdate Update() where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 20 | public IUpdate Update(object dywhere) where T1 : class => new SqlServerUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 21 | public IDelete Delete() where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 22 | public IDelete Delete(object dywhere) where T1 : class => new SqlServerDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 23 | 24 | public IAdo Ado { get; } 25 | public ICache Cache { get; } 26 | public ICodeFirst CodeFirst { get; } 27 | public IDbFirst DbFirst { get; } 28 | public SqlServerProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { 29 | if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.SqlServer"); 30 | 31 | this.InternalCommonUtils = new SqlServerUtils(this); 32 | this.InternalCommonExpression = new SqlServerExpression(this.InternalCommonUtils); 33 | 34 | this.Cache = new CacheProvider(cache, log); 35 | this.Ado = new SqlServerAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString); 36 | 37 | this.DbFirst = new SqlServerDbFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 38 | this.CodeFirst = new SqlServerCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 39 | } 40 | 41 | internal CommonUtils InternalCommonUtils { get; } 42 | internal CommonExpression InternalCommonExpression { get; } 43 | 44 | public void Transaction(Action handler) => Ado.Transaction(handler); 45 | 46 | public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /FreeSql/SqlServer/SqlServerUtils.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Data.Common; 6 | using System.Data.SqlClient; 7 | 8 | namespace FreeSql.SqlServer { 9 | 10 | class SqlServerUtils : CommonUtils { 11 | public SqlServerUtils(IFreeSql orm) : base(orm) { 12 | } 13 | 14 | internal override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { 15 | if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; 16 | else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower(); 17 | if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); 18 | var ret = new SqlParameter { ParameterName = $"@{parameterName}", Value = value }; 19 | var tp = _orm.CodeFirst.GetDbInfo(type)?.type; 20 | if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; 21 | _params?.Add(ret); 22 | return ret; 23 | } 24 | 25 | internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) => 26 | Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { 27 | if (value?.Equals(DateTime.MinValue) == true) value = new DateTime(1970, 1, 1); 28 | var ret = new SqlParameter { ParameterName = $"@{name}", Value = value }; 29 | var tp = _orm.CodeFirst.GetDbInfo(type)?.type; 30 | if (tp != null) ret.SqlDbType = (SqlDbType)tp.Value; 31 | return ret; 32 | }); 33 | 34 | internal override string FormatSql(string sql, params object[] args) => sql?.FormatSqlServer(args); 35 | internal override string QuoteSqlName(string name) => $"[{name.TrimStart('[').TrimEnd(']').Replace(".", "].[")}]"; 36 | internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; 37 | internal override string IsNull(string sql, object value) => $"isnull({sql}, {value})"; 38 | internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{(leftType.FullName == "System.String" ? left : $"cast({left} as nvarchar)")} + {(rightType.FullName == "System.String" ? right : $"cast({right} as nvarchar)")}"; 39 | internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; 40 | 41 | internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName; 42 | internal override string QuoteReadColumn(Type type, string columnName) => columnName; 43 | internal override string DbName => "SqlServer"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /FreeSql/Sqlite/Curd/SqliteDelete.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace FreeSql.Sqlite.Curd { 9 | 10 | class SqliteDelete : Internal.CommonProvider.DeleteProvider where T1 : class { 11 | public SqliteDelete(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 12 | : base(orm, commonUtils, commonExpression, dywhere) { 13 | } 14 | 15 | public override List ExecuteDeleted() { 16 | throw new NotImplementedException(); 17 | } 18 | public override Task> ExecuteDeletedAsync() { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /FreeSql/Sqlite/Curd/SqliteInsert.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace FreeSql.Sqlite.Curd { 9 | 10 | class SqliteInsert : Internal.CommonProvider.InsertProvider where T1 : class { 11 | public SqliteInsert(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression) 12 | : base(orm, commonUtils, commonExpression) { 13 | } 14 | 15 | public override long ExecuteIdentity() { 16 | var sql = this.ToSql(); 17 | if (string.IsNullOrEmpty(sql)) return 0; 18 | 19 | return long.TryParse(string.Concat(_orm.Ado.ExecuteScalar(CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; 20 | } 21 | async public override Task ExecuteIdentityAsync() { 22 | var sql = this.ToSql(); 23 | if (string.IsNullOrEmpty(sql)) return 0; 24 | 25 | return long.TryParse(string.Concat(await _orm.Ado.ExecuteScalarAsync(CommandType.Text, string.Concat(sql, "; SELECT last_insert_rowid();"), _params)), out var trylng) ? trylng : 0; 26 | } 27 | 28 | public override List ExecuteInserted() { 29 | throw new NotImplementedException(); 30 | } 31 | public override Task> ExecuteInsertedAsync() { 32 | throw new NotImplementedException(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /FreeSql/Sqlite/Curd/SqliteUpdate.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.Model; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace FreeSql.Sqlite.Curd { 11 | 12 | class SqliteUpdate : Internal.CommonProvider.UpdateProvider where T1 : class { 13 | 14 | public SqliteUpdate(IFreeSql orm, CommonUtils commonUtils, CommonExpression commonExpression, object dywhere) 15 | : base(orm, commonUtils, commonExpression, dywhere) { 16 | } 17 | 18 | public override List ExecuteUpdated() { 19 | throw new NotImplementedException(); 20 | } 21 | public override Task> ExecuteUpdatedAsync() { 22 | throw new NotImplementedException(); 23 | } 24 | 25 | protected override void ToSqlCase(StringBuilder caseWhen, ColumnInfo[] primarys) { 26 | if (_table.Primarys.Length == 1) { 27 | caseWhen.Append(_commonUtils.QuoteReadColumn(_table.Primarys.First().CsType, _commonUtils.QuoteSqlName(_table.Primarys.First().Attribute.Name))); 28 | return; 29 | } 30 | caseWhen.Append("CONCAT("); 31 | var pkidx = 0; 32 | foreach (var pk in _table.Primarys) { 33 | if (pkidx > 0) caseWhen.Append(", "); 34 | caseWhen.Append(_commonUtils.QuoteReadColumn(pk.CsType, _commonUtils.QuoteSqlName(pk.Attribute.Name))); 35 | ++pkidx; 36 | } 37 | caseWhen.Append(")"); 38 | } 39 | 40 | protected override void ToSqlWhen(StringBuilder sb, ColumnInfo[] primarys, object d) { 41 | if (_table.Primarys.Length == 1) { 42 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(_table.Primarys.First().CsName, out var tryp2) ? tryp2.GetValue(d) : null)); 43 | return; 44 | } 45 | sb.Append("CONCAT("); 46 | var pkidx = 0; 47 | foreach (var pk in _table.Primarys) { 48 | if (pkidx > 0) sb.Append(", "); 49 | sb.Append(_commonUtils.FormatSql("{0}", _table.Properties.TryGetValue(pk.CsName, out var tryp2) ? tryp2.GetValue(d) : null)); 50 | ++pkidx; 51 | } 52 | sb.Append(")"); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /FreeSql/Sqlite/SqliteAdo/SqliteAdo.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using Microsoft.Extensions.Logging; 3 | using SafeObjectPool; 4 | using System; 5 | using System.Collections; 6 | using System.Data.Common; 7 | using System.Data.SQLite; 8 | using System.Text; 9 | using System.Threading; 10 | 11 | namespace FreeSql.Sqlite { 12 | class SqliteAdo : FreeSql.Internal.CommonProvider.AdoProvider { 13 | CommonUtils _util; 14 | 15 | public SqliteAdo() : base(null, null) { } 16 | public SqliteAdo(CommonUtils util, ICache cache, ILogger log, string masterConnectionString, string[] slaveConnectionStrings) : base(cache, log) { 17 | this._util = util; 18 | MasterPool = new SqliteConnectionPool("主库", masterConnectionString, null, null); 19 | if (slaveConnectionStrings != null) { 20 | foreach (var slaveConnectionString in slaveConnectionStrings) { 21 | var slavePool = new SqliteConnectionPool($"从库{SlavePools.Count + 1}", slaveConnectionString, () => Interlocked.Decrement(ref slaveUnavailables), () => Interlocked.Increment(ref slaveUnavailables)); 22 | SlavePools.Add(slavePool); 23 | } 24 | } 25 | } 26 | static DateTime dt1970 = new DateTime(1970, 1, 1); 27 | public override object AddslashesProcessParam(object param) { 28 | if (param == null) return "NULL"; 29 | if (param is bool || param is bool?) 30 | return (bool)param ? 1 : 0; 31 | else if (param is string) 32 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 33 | else if (param is Enum) 34 | return ((Enum)param).ToInt64(); 35 | else if (decimal.TryParse(string.Concat(param), out var trydec)) 36 | return param; 37 | else if (param is DateTime) 38 | return string.Concat("'", ((DateTime)param).ToString("yyyy-MM-dd HH:mm:ss"), "'"); 39 | else if (param is DateTime?) 40 | return string.Concat("'", (param as DateTime?).Value.ToString("yyyy-MM-dd HH:mm:ss"), "'"); 41 | else if (param is TimeSpan) 42 | return ((TimeSpan)param).Ticks / 10000; 43 | else if (param is TimeSpan?) 44 | return (param as TimeSpan?).Value.Ticks / 10000; 45 | else if (param is MygisGeometry) 46 | return (param as MygisGeometry).AsText(); 47 | else if (param is IEnumerable) { 48 | var sb = new StringBuilder(); 49 | var ie = param as IEnumerable; 50 | foreach (var z in ie) sb.Append(",").Append(AddslashesProcessParam(z)); 51 | return sb.Length == 0 ? "(NULL)" : sb.Remove(0, 1).Insert(0, "(").Append(")").ToString(); 52 | } 53 | return string.Concat("'", param.ToString().Replace("'", "''"), "'"); 54 | //if (param is string) return string.Concat('N', nparms[a]); 55 | } 56 | 57 | protected override DbCommand CreateCommand() { 58 | return new SQLiteCommand(); 59 | } 60 | 61 | protected override void ReturnConnection(ObjectPool pool, Object conn, Exception ex) { 62 | (pool as SqliteConnectionPool).Return(conn, ex); 63 | } 64 | 65 | protected override DbParameter[] GetDbParamtersByObject(string sql, object obj) => _util.GetDbParamtersByObject(sql, obj); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /FreeSql/Sqlite/SqliteProvider.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.CommonProvider; 3 | using FreeSql.Sqlite.Curd; 4 | using Microsoft.Extensions.Caching.Distributed; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Data.Common; 10 | 11 | namespace FreeSql.Sqlite { 12 | 13 | class SqliteProvider : IFreeSql { 14 | 15 | public ISelect Select() where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 16 | public ISelect Select(object dywhere) where T1 : class => new SqliteSelect(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 17 | public IInsert Insert() where T1 : class => new SqliteInsert(this, this.InternalCommonUtils, this.InternalCommonExpression); 18 | public IInsert Insert(T1 source) where T1 : class => this.Insert().AppendData(source); 19 | public IInsert Insert(IEnumerable source) where T1 : class => this.Insert().AppendData(source); 20 | public IUpdate Update() where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 21 | public IUpdate Update(object dywhere) where T1 : class => new SqliteUpdate(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 22 | public IDelete Delete() where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, null); 23 | public IDelete Delete(object dywhere) where T1 : class => new SqliteDelete(this, this.InternalCommonUtils, this.InternalCommonExpression, dywhere); 24 | 25 | public IAdo Ado { get; } 26 | public ICache Cache { get; } 27 | public ICodeFirst CodeFirst { get; } 28 | public IDbFirst DbFirst { get { throw new NotImplementedException(); } } 29 | public SqliteProvider(IDistributedCache cache, ILogger log, string masterConnectionString, string[] slaveConnectionString) { 30 | if (log == null) log = new LoggerFactory(new[] { new Microsoft.Extensions.Logging.Debug.DebugLoggerProvider() }).CreateLogger("FreeSql.Sqlite"); 31 | 32 | this.InternalCommonUtils = new SqliteUtils(this); 33 | this.InternalCommonExpression = new SqliteExpression(this.InternalCommonUtils); 34 | 35 | this.Cache = new CacheProvider(cache, log); 36 | this.Ado = new SqliteAdo(this.InternalCommonUtils, this.Cache, log, masterConnectionString, slaveConnectionString); 37 | 38 | this.CodeFirst = new SqliteCodeFirst(this, this.InternalCommonUtils, this.InternalCommonExpression); 39 | } 40 | 41 | internal CommonUtils InternalCommonUtils { get; } 42 | internal CommonExpression InternalCommonExpression { get; } 43 | 44 | public void Transaction(Action handler) => Ado.Transaction(handler); 45 | 46 | public void Transaction(Action handler, TimeSpan timeout) => Ado.Transaction(handler, timeout); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /FreeSql/Sqlite/SqliteUtils.cs: -------------------------------------------------------------------------------- 1 | using FreeSql.Internal; 2 | using FreeSql.Internal.Model; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Data; 6 | using System.Data.Common; 7 | using System.Data.SQLite; 8 | 9 | namespace FreeSql.Sqlite { 10 | 11 | class SqliteUtils : CommonUtils { 12 | public SqliteUtils(IFreeSql orm) : base(orm) { 13 | } 14 | 15 | internal override DbParameter AppendParamter(List _params, string parameterName, Type type, object value) { 16 | if (string.IsNullOrEmpty(parameterName)) parameterName = $"p_{_params?.Count}"; 17 | else if (_orm.CodeFirst.IsSyncStructureToLower) parameterName = parameterName.ToLower(); 18 | var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; 19 | switch (dbtype) { 20 | case DbType.Guid: 21 | if (value == null) value = null; 22 | else value = ((Guid)value).ToString(); 23 | dbtype = DbType.String; 24 | break; 25 | case DbType.Time: 26 | if (value == null) value = null; 27 | else value = ((TimeSpan)value).Ticks / 10000; 28 | dbtype = DbType.Int64; 29 | break; 30 | } 31 | var ret = new SQLiteParameter { ParameterName = $"@{parameterName}", DbType = dbtype, Value = value }; 32 | _params?.Add(ret); 33 | return ret; 34 | } 35 | 36 | internal override DbParameter[] GetDbParamtersByObject(string sql, object obj) => 37 | Utils.GetDbParamtersByObject(sql, obj, "@", (name, type, value) => { 38 | var dbtype = (DbType)_orm.CodeFirst.GetDbInfo(type)?.type; 39 | switch (dbtype) { 40 | case DbType.Guid: 41 | if (value == null) value = null; 42 | else value = ((Guid)value).ToString(); 43 | dbtype = DbType.String; 44 | break; 45 | case DbType.Time: 46 | if (value == null) value = null; 47 | else value = ((TimeSpan)value).Ticks / 10000; 48 | dbtype = DbType.Int64; 49 | break; 50 | } 51 | var ret = new SQLiteParameter { ParameterName = $"@{name}", DbType = dbtype, Value = value }; 52 | return ret; 53 | }); 54 | 55 | internal override string FormatSql(string sql, params object[] args) => sql?.FormatSqlite(args); 56 | internal override string QuoteSqlName(string name) => $"\"{name.Trim('"').Replace(".", "\".\"")}\""; 57 | internal override string QuoteParamterName(string name) => $"@{(_orm.CodeFirst.IsSyncStructureToLower ? name.ToLower() : name)}"; 58 | internal override string IsNull(string sql, object value) => $"ifnull({sql}, {value})"; 59 | internal override string StringConcat(string left, string right, Type leftType, Type rightType) => $"{left} || {right}"; 60 | internal override string Mod(string left, string right, Type leftType, Type rightType) => $"{left} % {right}"; 61 | 62 | internal override string QuoteWriteParamter(Type type, string paramterName) => paramterName; 63 | internal override string QuoteReadColumn(Type type, string columnName) => columnName; 64 | internal override string DbName => "Sqlite"; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 YeXiangQin 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 | -------------------------------------------------------------------------------- /Templates/MySql/rich-entity-navigation-object/Const.cs: -------------------------------------------------------------------------------- 1 | public static class Const { 2 | public static IFreeSql mysql = new FreeSql.FreeSqlBuilder() 3 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 4 | .Build(); 5 | } 6 | -------------------------------------------------------------------------------- /Templates/MySql/rich-entity-navigation-object/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/MySql/simple-entity-navigation-object/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/MySql/simple-entity/Model/for-table.cs.freesql: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using FreeSql.DataAnnotations; 9 | {% 10 | var dbf = dbfirst as FreeSql.IDbFirst; 11 | var cols = (table.Columns as List); 12 | 13 | Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1); 14 | Func GetCsType = cola3 => { 15 | if (cola3.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Enum || cola3.DbType == (int)MySql.Data.MySqlClient.MySqlDbType.Set) { 16 | return $"{UString(cola3.Table.Name)}{cola3.Name.ToUpper()}{(cola3.IsNullable ? "?" : "")}"; 17 | } 18 | return dbf.GetCsType(cola3); 19 | }; 20 | %} 21 | namespace test.Model { 22 | 23 | [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})] 24 | public partial class {#UString(table.Name)} {{for col,index in table.Columns} 25 | {if string.IsNullOrEmpty(col.Coment) == false}/// 26 | /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} 27 | /// {/if} 28 | [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] 29 | public {#GetCsType(col)} {#UString(col.Name)} { get; set; } 30 | {/for} 31 | } 32 | {include ../../include/enumtype.tpl} 33 | } -------------------------------------------------------------------------------- /Templates/MySql/simple-entity/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/PostgreSQL/rich-entity-navigation-object/Const.cs: -------------------------------------------------------------------------------- 1 | public static class Const { 2 | public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() 3 | .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 4 | .Build(); 5 | } 6 | -------------------------------------------------------------------------------- /Templates/PostgreSQL/rich-entity-navigation-object/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/PostgreSQL/simple-entity-navigation-object/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/PostgreSQL/simple-entity/Model/for-table.cs.freesql: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using FreeSql.DataAnnotations; 9 | using System.Net; 10 | using Newtonsoft.Json.Linq; 11 | using System.Net.NetworkInformation; 12 | using NpgsqlTypes; 13 | using Npgsql.LegacyPostgis; 14 | {% 15 | var dbf = dbfirst as FreeSql.IDbFirst; 16 | var cols = (table.Columns as List); 17 | 18 | Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1); 19 | Func GetCsType = cola3 => { 20 | 21 | return dbf.GetCsType(cola3); 22 | }; 23 | %} 24 | namespace test.Model { 25 | 26 | [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})] 27 | public partial class {#UString(table.Name)} {{for col,index in table.Columns} 28 | {if string.IsNullOrEmpty(col.Coment) == false}/// 29 | /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} 30 | /// {/if} 31 | [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] 32 | public {#GetCsType(col)} {#UString(col.Name)} { get; set; } 33 | {/for} 34 | } 35 | } -------------------------------------------------------------------------------- /Templates/PostgreSQL/simple-entity/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/SqlServer/rich-entity-navigation-object/Const.cs: -------------------------------------------------------------------------------- 1 | public static class Const { 2 | public static IFreeSql sqlserver = new FreeSql.FreeSqlBuilder() 3 | .UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 4 | .Build(); 5 | } 6 | -------------------------------------------------------------------------------- /Templates/SqlServer/rich-entity-navigation-object/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/SqlServer/simple-entity-navigation-object/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` -------------------------------------------------------------------------------- /Templates/SqlServer/simple-entity/Model/for-table.cs.freesql: -------------------------------------------------------------------------------- 1 | {%if (table.Type == DbTableType.StoreProcedure) { 2 | print("return;"); 3 | return rTn; 4 | } 5 | %}using System; 6 | using System.Collections; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Reflection; 10 | using System.Threading.Tasks; 11 | using Newtonsoft.Json; 12 | using FreeSql.DataAnnotations; 13 | {% 14 | var dbf = dbfirst as FreeSql.IDbFirst; 15 | var cols = (table.Columns as List); 16 | 17 | Func UString = stra => stra.Substring(0, 1).ToUpper() + stra.Substring(1); 18 | Func GetCsType = cola3 => { 19 | return dbf.GetCsType(cola3); 20 | }; 21 | %} 22 | namespace test.Model { 23 | 24 | [JsonObject(MemberSerialization.OptIn), Table(Name = "{#!string.IsNullOrEmpty(table.Schema) ? table.Schema + "." : ""}{#table.Name}"{if cols.Where(cola003 => cola003.Name.ToLower() == "is_deleted" || cola003.Name.ToLower() == "isdeleted").Any()}, SelectFilter = "a.IsDeleted = 1"{/if})] 25 | public partial class {#UString(table.Name)} {{for col,index in table.Columns} 26 | {if string.IsNullOrEmpty(col.Coment) == false}/// 27 | /// {#col.Coment.Replace("\r\n", "\n").Replace("\n", "\r\n /// ")} 28 | /// {/if} 29 | [JsonProperty, Column(Name = "{#col.Name}", DbType = "{#col.DbTypeTextFull}"{if col.IsPrimary == true}, IsPrimary = true{/if}{if col.IsIdentity == true}, IsIdentity = true{/if}{if col.IsNullable == true}, IsNullable = true{/if})] 30 | public {#GetCsType(col)} {#UString(col.Name)} { get; set; } 31 | {/for} 32 | } 33 | } -------------------------------------------------------------------------------- /Templates/SqlServer/simple-entity/readme.md: -------------------------------------------------------------------------------- 1 | # 生成器 2 | 3 | 生成器是基于 dbfirst 开发的辅助工具,适用老项目一键生成实体。生成器采用模板的方式,作者实现了三种生成模板: 4 | 5 | | 模板名称 | 类型映射 | 外键导航属性 | 缓存管理 | 失血 | 贫血 | 充血 | 6 | | ------------- | - | - |- | - |- | - | 7 | | simple-entity | √ | X | X | √ | X | X | 8 | | simple-entity-navigation-object | √ | √ | X | √ | X | X | 9 | | rich-entity-navigation-object | √ | √ | √ | X | √ | X | 10 | 11 | 模板在项目目录:/Templates/MySql 12 | 13 | > 更多模板逐步开发中。。。 14 | 15 | ```csharp 16 | //定义 mysql FreeSql 17 | var mysql = new FreeSql.FreeSqlBuilder() 18 | .UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=10") 19 | .Build(); 20 | 21 | //创建模板生成类现实 22 | var gen = new FreeSql.Generator.TemplateGenerator(); 23 | gen.Build(mysql.DbFirst, 24 | @"C:\Users\28810\Desktop\github\FreeSql\Templates\MySql\simple-entity", //模板目录(事先下载) 25 | @"C:\Users\28810\Desktop\新建文件夹 (9)", //生成后保存的目录 26 | "cccddd" //数据库 27 | ); 28 | ``` 29 | 30 | ## 模板语法 31 | 32 | ```html 33 | 34 | 35 | {#title} 36 | 37 | 38 | 39 | 40 | {#表达式} 41 | {##表达式} 当表达式可能发生runtime错误时使用,性能没有上面的高 42 | 43 | 44 | {include ../header.html} 45 |
46 |

aaa

47 |

bbb {#i}

48 |

ccc {#i}

49 |
50 | 51 | 52 | {module module_name1 parms1, 2, 3...} 53 | {/module} 54 | {module module_name2 parms1, 2, 3...} 55 | {/module} 56 | 57 | 58 | {import ../module.html as myname} 59 | {#myname.module_name(parms1, 2, 3...)} 60 | 61 | 62 | {extends ../inc/layout.html} 63 | {block body}{/block} 64 | 65 | 66 | {% 67 | for (var a = 0; a < 100; a++) 68 | print(a); 69 | %} 70 | 71 | 72 | {if i === 50} 73 | {elseif i > 60} 74 | {else} 75 | {/if} 76 | 77 | 78 | {for i 1,101} 可自定义名 {for index2 表达式1 in 表达式2} 79 | 80 | {for item,index in items} 可选参数称 index 81 | 可自定义名 {for item2, index99 in 数组表达式} 82 | 83 | {for key,item,index on json} 可选参数 item, index, 84 | 可自定义名 {for key2, item2, index99 in 对象表达式} 85 | {/for} 86 | 87 | 88 | {miss} 89 | 此块内容不被bmw.js解析 90 | {/miss} 91 | 92 | 93 | 94 | ``` --------------------------------------------------------------------------------