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 条件
-
-
-
-