From 4ddf4c01a60044a046ffbaff871b66d0a3d44ab5 Mon Sep 17 00:00:00 2001 From: 28810 <28810@YEXIANGQIN> Date: Sat, 20 Jun 2020 17:45:15 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20=20SqlExt.Case().When(?= =?UTF-8?q?..).End()=20=E8=A1=A8=E8=BE=BE=E5=BC=8F=E5=87=BD=E6=95=B0?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql.DbContext/FreeSql.DbContext.xml | 16 - FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 30 ++ .../FreeSqlGlobalExpressionCallExtensions.cs | 62 +++- FreeSql/FreeSql.xml | 312 ++++++++---------- 4 files changed, 223 insertions(+), 197 deletions(-) diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml index 4854f49c..132d875e 100644 --- a/FreeSql.DbContext/FreeSql.DbContext.xml +++ b/FreeSql.DbContext/FreeSql.DbContext.xml @@ -125,13 +125,6 @@ 清空状态数据 - - - 根据 lambda 条件删除数据 - - - - 添加 @@ -486,14 +479,5 @@ - - - 批量注入 Repository,可以参考代码自行调整 - - - - - - diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 762fdaa9..a0be59b2 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -155,6 +155,36 @@ namespace FreeSql.Tests [Fact] public void Test03() { + var sqlextCase = g.sqlserver.Select() + .InnerJoin((a, b) => b.Id == a.Id) + .ToSql((a, b) => new + { + Id = a.Id, + EdiId = b.Id, + case1 = SqlExt.Case() + .When(a.Id == 1, 10) + .When(a.Id == 2, 11) + .When(a.Id == 3, 12) + .When(a.Id == 4, 13) + .When(a.Id == 5, SqlExt.Case().When(b.Id == 1, 10000).Else(999).End()) + .End() + }); + var sqlextCaseToList = g.sqlserver.Select() + .InnerJoin((a, b) => b.Id == a.Id) + .ToList((a, b) => new + { + Id = a.Id, + EdiId = b.Id, + case1 = SqlExt.Case() + .When(a.Id == 1, 10) + .When(a.Id == 2, 11) + .When(a.Id == 3, 12) + .When(a.Id == 4, 13) + .When(a.Id == 5, SqlExt.Case().When(b.Id == 1, 10000).Else(999).End()) + .End() + }); + + var sqlextOver = g.sqlserver.Select() .InnerJoin((a, b) => b.Id == a.Id) .ToSql((a, b) => new diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs index c8de533c..7fe955da 100644 --- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs +++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs @@ -1,5 +1,7 @@ using FreeSql.DataAnnotations; using System; +using System.Collections.Generic; +using System.Linq; using System.Text; using System.Threading; @@ -48,8 +50,6 @@ namespace FreeSql public static class SqlExt { public static ThreadLocal expContext = new ThreadLocal(); - static ThreadLocal expSb = new ThreadLocal(); - static ThreadLocal expSbIsOrderBy = new ThreadLocal(); public static ISqlOver Rank() => Over("RANK()"); public static ISqlOver DenseRank() => Over("DENSE_RANK()"); @@ -61,32 +61,34 @@ namespace FreeSql public static ISqlOver RowNumber() => Over("ROW_NUMBER()"); #region .. over([partition by ..] order by ...) + static ThreadLocal expOverSb = new ThreadLocal(); + static ThreadLocal expOverSbIsOrderBy = new ThreadLocal(); static ISqlOver Over(string sqlFunc) { - expSb.Value = new StringBuilder(); - expSbIsOrderBy.Value = false; - expSb.Value.Append($"{sqlFunc} "); + expOverSb.Value = new StringBuilder(); + expOverSbIsOrderBy.Value = false; + expOverSb.Value.Append($"{sqlFunc} "); return null; } public static ISqlOver Over(this ISqlOver that) { - expSb.Value.Append("OVER("); + expOverSb.Value.Append("OVER("); return that; } public static ISqlOver PartitionBy(this ISqlOver that, object column) { - expSb.Value.Append("PARTITION BY ").Append(expContext.Value.ParsedContent["column"]).Append(","); + expOverSb.Value.Append("PARTITION BY ").Append(expContext.Value.ParsedContent["column"]).Append(","); return that; } public static ISqlOver OrderBy(this ISqlOver that, object column) => OrderBy(that, false); public static ISqlOver OrderByDescending(this ISqlOver that, object column) => OrderBy(that, true); static ISqlOver OrderBy(this ISqlOver that, bool isDesc) { - var sb = expSb.Value; - if (expSbIsOrderBy.Value == false) + var sb = expOverSb.Value; + if (expOverSbIsOrderBy.Value == false) { sb.Append("ORDER BY "); - expSbIsOrderBy.Value = true; + expOverSbIsOrderBy.Value = true; } sb.Append(expContext.Value.ParsedContent["column"]); if (isDesc) sb.Append(" desc"); @@ -95,12 +97,48 @@ namespace FreeSql } public static TValue ToValue(this ISqlOver that) { - var sb = expSb.Value.ToString().TrimEnd(','); - expSb.Value.Clear(); + var sb = expOverSb.Value.ToString().TrimEnd(','); + expOverSb.Value.Clear(); expContext.Value.Result = $"{sb})"; return default; } public interface ISqlOver { } #endregion + + #region case when .. then .. when .. then .. end + static ThreadLocal> expCaseWhenEndSb = new ThreadLocal>(); + public static ICaseWhenEnd Case() + { + if (expCaseWhenEndSb.Value == null) expCaseWhenEndSb.Value = new List(); + expCaseWhenEndSb.Value.Add(new StringBuilder().Append("CASE ")); + return null; + } + public static ICaseWhenEnd When(this ICaseWhenEnd that, bool test, TValue then) + { + expCaseWhenEndSb.Value.Last().Append("\r\n WHEN ").Append(expContext.Value.ParsedContent["test"]).Append(" THEN ").Append(expContext.Value.ParsedContent["then"]); + return null; + } + public static ICaseWhenEnd When(this ICaseWhenEnd that, bool test, TValue then) + { + expCaseWhenEndSb.Value.Last().Append("\r\n WHEN ").Append(expContext.Value.ParsedContent["test"]).Append(" THEN ").Append(expContext.Value.ParsedContent["then"]); + return null; + } + public static ICaseWhenEnd Else(this ICaseWhenEnd that, TValue then) + { + expCaseWhenEndSb.Value.Last().Append("\r\n ELSE ").Append(expContext.Value.ParsedContent["then"]); + return null; + } + public static TValue End(this ICaseWhenEnd that) + { + var sb = expCaseWhenEndSb.Value; + var sql = sb.Last().Append("\r\nEND").ToString(); + sb.Last().Clear(); + sb.RemoveAt(sb.Count - 1); + expContext.Value.Result = sql; + return default; + } + public interface ICaseWhenEnd { } + public interface ICaseWhenEnd { } + #endregion } } \ No newline at end of file diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index 01940f0f..7f3b7221 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -2417,6 +2417,137 @@ + + + 查询,若使用读写分离,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 + + + + + + + + + 查询,ExecuteReaderAsync(dr => {}, "select * from user where age > ?age", new { age = 25 }) + + + + + + + 查询 + + + + + + + 查询,ExecuteArrayAsync("select * from user where age > ?age", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataSetAsync("select * from user where age > ?age; select 2", new { age = 25 }) + + + + + + + + 查询 + + + + + + + 查询,ExecuteDataTableAsync("select * from user where age > ?age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteNonQueryAsync("delete from user where age > ?age", new { age = 25 }) + + + + + + + + 在【主库】执行 + + + + + + + + 在【主库】执行,ExecuteScalarAsync("select 1 from user where age > ?age", new { age = 25 }) + + + + + + + + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,QueryAsync<User>("select * from user where age > ?age", new { age = 25 }) + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 }) + + + + + + + + + + 执行SQL返回对象集合,Query<User>("select * from user where age > ?age; select * from address", new { age = 25 }) + + + + + + 可自定义解析表达式 @@ -3063,6 +3194,12 @@ 超时 + + + 获取资源 + + + 使用完毕后,归还资源 @@ -3133,6 +3270,12 @@ 资源对象 + + + 从对象池获取对象成功的时候触发,通过该方法统计或初始化对象 + + 资源对象 + 归还对象给对象池的时候触发 @@ -3774,172 +3917,3 @@ -xpression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})"> - - 使用 or 拼接两个 lambda 表达式 - - - - - - 使用 or 拼接两个 lambda 表达式 - - - true 时生效 - - - - - - 将 lambda 表达式取反 - - - true 时生效 - - - - - 生成类似Mongodb的ObjectId有序、不重复Guid - - - - - - 插入数据 - - - - - - - 插入数据,传入实体 - - - - - - - - 插入数据,传入实体数组 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入数据,传入实体集合 - - - - - - - - 插入或更新数据 - MySql: on duplicate key update - PostgreSQL: on conflict do update - SqlServer: merge into - Oracle: merge into - Sqlite: replace into - Dameng: merge into - 注意:还可以使用 FreeSql.Repository 的 InsertOrUpdate 方法 - - - - - - - 修改数据 - - - - - - - 修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 查询数据 - - - - - - - 查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 删除数据 - - - - - - - 删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1} - - - 主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合 - - - - - 开启事务(不支持异步) - v1.5.0 关闭了线程事务超时自动提交的机制 - - 事务体 () => {} - - - - 开启事务(不支持异步) - v1.5.0 关闭了线程事务超时自动提交的机制 - - - 事务体 () => {} - - - - 数据库访问对象 - - - - - 所有拦截方法都在这里 - - - - - CodeFirst 模式开发相关方法 - - - - - DbFirst 模式开发相关方法 - - - - - 全局过滤设置,可默认附加为 Select/Update/Delete 条件 - - - -