From 800640ada936a178efd01461306533767bc111bc Mon Sep 17 00:00:00 2001 From: 2881099 <2881099@qq.com> Date: Mon, 4 Nov 2024 16:23:47 +0800 Subject: [PATCH] =?UTF-8?q?-=20=E4=BC=98=E5=8C=96=20=E5=AD=90=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=B8=AD=20UnionAll=20=E7=9A=84=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FreeSql/FreeSql.xml | 232 ++++++++++++++------------- FreeSql/Internal/CommonExpression.cs | 28 ++-- 2 files changed, 139 insertions(+), 121 deletions(-) diff --git a/FreeSql/FreeSql.xml b/FreeSql/FreeSql.xml index c2fac3dd8..c7899724b 100644 --- a/FreeSql/FreeSql.xml +++ b/FreeSql/FreeSql.xml @@ -1087,93 +1087,6 @@ - - - 动态创建实体类型 - - - - - 配置Class - - 类名 - 类标记的特性[Table(Name = "xxx")] [Index(xxxx)] - - - - - 获取类型构建器,可作为要构建的Type来引用 - - - - - 配置属性 - - 属性名称 - 属性类型 - 属性标记的特性-支持多个 - - - - - 配置属性 - - 属性名称 - 属性类型 - 该属性是否重写父类属性 - 属性标记的特性-支持多个 - - - - - 配置属性 - - 属性名称 - 属性类型 - 该属性是否重写父类属性 - 属性默认值 - 属性标记的特性-支持多个 - - - - - 配置父类 - - 父类类型 - - - - - Override属性 - - - - - - Emit动态创建出Class - Type - - - - - - Emit动态创建出Class - Type,不附带获取TableInfo - - - - - - 首字母小写 - - - - - - - 首字母大写 - - - - 获取实体的主键值,以 "*|_,[,_|*" 分割,当任意一个主键属性无值时,返回 "" @@ -5914,28 +5827,6 @@ 请使用 fsql.InsertDict(dict) 方法插入字典数据 - - - 动态构建Class Type - - - - - - 根据字典,创建 table 对应的实体对象 - - - - - - - - 根据实体对象,创建 table 对应的字典 - - - - - C#: that >= between && that <= and @@ -6472,3 +6363,126 @@ + + + + + 插入数据,传入实体集合 + + + + + + + + 插入数据,传入实体集合 + + + + + + + + 插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下: + MySql 5.6+: on duplicate key update + PostgreSQL 9.4+: on conflict do update + SqlServer 2008+: merge into + Oracle 11+: merge into + Sqlite: replace into + DuckDB: on conflict do update + 达梦: merge into + 人大金仓:on conflict do update + 神通:merge into + MsAccess:不支持 + 注意区别: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 条件 + + + + diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index dd3ffc8ad..a6a673a5a 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -1233,6 +1233,8 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) var exp3tmp = exp3.Object; if (exp3.Method.Name == "Any" && exp3tmp != null && anyArgs.Any()) exp3Stack.Push(Expression.Call(exp3tmp, callType.GetMethod("Where", anyArgs.Select(a => a.Type).ToArray()), anyArgs.ToArray())); + if (tsc.style == ExpressionStyle.ReturnISelect && typeof(ISelect0).IsAssignableFrom(exp3.Method.ReturnType)) + exp3Stack.Push(exp3); //WithTempQuery 或第后一个方法附加到解析或运行,Any/Count/Sum/Min/Max/Avg/ToList/ToOne/First 等方法不需要 while (exp3tmp != null) { exp3Stack.Push(exp3tmp); @@ -1404,16 +1406,17 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) else if (arg3Exp is NewArrayExpression arg3ExpNewArray && arg3ExpNewArray?.Expressions.Any() == true && typeof(ISelect0).IsAssignableFrom(arg3ExpNewArray.Expressions[0].Type)) { - var arg3ExpNewArrayTables = fsqltables.Select(tbcopy => new SelectTableInfo - { - Alias = tbcopy.Alias, - On = "1=1", - Table = tbcopy.Table, - Type = SelectTableInfoType.Parent, - Parameter = tbcopy.Parameter - }).ToList(); - args[a] = arg3ExpNewArray.Expressions.Select((b, bi) => + Array arg3Values = Array.CreateInstance(arg3ExpNewArray.Expressions[0].Type, arg3ExpNewArray.Expressions.Count); + for (var arg3Idx = 0;arg3Idx < arg3ExpNewArray.Expressions.Count; arg3Idx++) { + var arg3ExpNewArrayTables = fsqltables.Select(tbcopy => new SelectTableInfo + { + Alias = tbcopy.Alias, + On = "1=1", + Table = tbcopy.Table, + Type = SelectTableInfoType.Parent, + Parameter = tbcopy.Parameter + }).ToList(); var thenTsc = new ExpTSC { _tables = arg3ExpNewArrayTables, @@ -1426,9 +1429,10 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) whereGlobalFilter = tsc.whereGlobalFilter, dbParams = tsc.dbParams }; - ExpressionLambdaToSql(b, thenTsc); - return thenTsc._returnISelect; - }).ToArray(); + ExpressionLambdaToSql(arg3ExpNewArray.Expressions[arg3Idx], thenTsc); + arg3Values.SetValue(thenTsc._returnISelect, arg3Idx); + } + args[a] = arg3Values; } else if (typeof(ISelect0).IsAssignableFrom(arg3Exp.Type)) {