- 增加 UnionALL 联合查询;#1106 #1104 #668 #478 #432 #213 #138

This commit is contained in:
2881099 2022-08-26 18:01:58 +08:00
parent d154a463a5
commit 4b9c4e724d
9 changed files with 341 additions and 221 deletions

View File

@ -8,6 +8,7 @@ using Newtonsoft.Json.Linq;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common;
using System.Data.Odbc; using System.Data.Odbc;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Data.SQLite; using System.Data.SQLite;
@ -388,6 +389,45 @@ namespace base_entity
BaseEntity.Initialization(fsql, () => _asyncUow.Value); BaseEntity.Initialization(fsql, () => _asyncUow.Value);
#endregion #endregion
var dbpars = new List<DbParameter>();
var a1id1 = Guid.NewGuid();
var a1id2 = Guid.NewGuid();
//fsql.CodeFirst.IsGenerateCommandParameterWithLambda = true;
var sql1a0 = fsql.Select<User1>()
.WithParameters(dbpars)
.Where(a => a.Id == a1id1)
.UnionAll(
fsql.Select<User1>()
.WithParameters(dbpars)
.Where(a => a.Id == a1id2)
)
.Where(a => a.Id == a1id1 || a.Id == a1id2)
.ToSql();
var sql1a1 = fsql.Select<User1>()
.Where(a => a.Id == a1id1)
.UnionAll(
fsql.Select<User1>()
.Where(a => a.Id == a1id2)
)
.Where(a => a.Id == a1id1 || a.Id == a1id2)
.ToSql();
var sql1a2 = fsql.Select<User1, UserGroup>()
.InnerJoin((a,b)=> a.GroupId == b.Id)
.Where((a, b) => a.Id == a1id1)
.WithTempQuery((a, b) => new { user = a, group = b }) //匿名类型
.UnionAll(
fsql.Select<User1, UserGroup>()
.InnerJoin((a, b) => a.GroupId == b.Id)
.Where((a, b) => a.Id == a1id2)
.WithTempQuery((a, b) => new { user = a, group = b }) //匿名类型
)
.Where(a => a.user.Id == a1id1 || a.user.Id == a1id2)
.ToSql();
var ddlsql01 = fsql.CodeFirst.GetComparisonDDLStatements<StringNulable>(); var ddlsql01 = fsql.CodeFirst.GetComparisonDDLStatements<StringNulable>();

View File

@ -434,6 +434,77 @@ WHERE (a.[rownum] = 1)";
Assert.Equal(list01[2].item.Nickname, "name03"); Assert.Equal(list01[2].item.Nickname, "name03");
var sql0111 = fsql.Select<SingleTablePartitionBy_User>()
.WithTempQuery(a => new
{
item = a,
rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue()
})
.Where(a => a.rownum == 1)
.UnionAll(
fsql.Select<SingleTablePartitionBy_User>()
.WithTempQuery(a => new
{
item = a,
rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderByDescending(a.Id).ToValue()
})
.Where(a => a.rownum == 2)
)
.Where(a => a.rownum == 1 || a.rownum == 2)
.ToSql();
var assertSql0111 = @"SELECT *
FROM ( SELECT *
FROM (
SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id]) [rownum]
FROM [SingleTablePartitionBy_User] a ) a
WHERE (a.[rownum] = 1)
UNION ALL
SELECT *
FROM (
SELECT a.[Id], a.[Nickname], row_number() over( partition by a.[Nickname] order by a.[Id] desc) [rownum]
FROM [SingleTablePartitionBy_User] a ) a
WHERE (a.[rownum] = 2) ) a
WHERE ((a.[rownum] = 1 OR a.[rownum] = 2))";
Assert.Equal(assertSql0111, sql0111);
var sel0111 = fsql.Select<SingleTablePartitionBy_User>()
.WithTempQuery(a => new
{
item = a,
rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderBy(a.Id).ToValue()
})
.Where(a => a.rownum == 1)
.UnionAll(
fsql.Select<SingleTablePartitionBy_User>()
.WithTempQuery(a => new
{
item = a,
rownum = SqlExt.RowNumber().Over().PartitionBy(a.Nickname).OrderByDescending(a.Id).ToValue()
})
.Where(a => a.rownum == 2)
)
.Where(a => a.rownum == 1 || a.rownum == 2);
Assert.Equal(assertSql0111, sel0111.ToSql());
var list0111 = sel0111.ToList();
Assert.Equal(5, list0111.Count);
Assert.Equal(list0111[0].rownum, 1);
Assert.Equal(list0111[0].item.Id, 1);
Assert.Equal(list0111[0].item.Nickname, "name01");
Assert.Equal(list0111[1].rownum, 1);
Assert.Equal(list0111[1].item.Id, 4);
Assert.Equal(list0111[1].item.Nickname, "name02");
Assert.Equal(list0111[2].rownum, 1);
Assert.Equal(list0111[2].item.Id, 5);
Assert.Equal(list0111[2].item.Nickname, "name03");
Assert.Equal(list0111[3].rownum, 2);
Assert.Equal(list0111[3].item.Id, 2);
Assert.Equal(list0111[3].item.Nickname, "name01");
Assert.Equal(list0111[4].rownum, 2);
Assert.Equal(list0111[4].item.Id, 5);
Assert.Equal(list0111[4].item.Nickname, "name03");
var sql011 = fsql.Select<SingleTablePartitionBy_User>() var sql011 = fsql.Select<SingleTablePartitionBy_User>()
.GroupBy(a => a.Nickname) .GroupBy(a => a.Nickname)
.WithTempQuery(g => new { min = g.Min(g.Value.Id) }) .WithTempQuery(g => new { min = g.Min(g.Value.Id) })

View File

@ -263,7 +263,7 @@ namespace FreeSql.Tests
var ddlsql = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(testInsertNullable), "tb123123"); var ddlsql = g.sqlite.CodeFirst.GetComparisonDDLStatements(typeof(testInsertNullable), "tb123123");
Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb123123"" ( Assert.Equal(@"CREATE TABLE IF NOT EXISTS ""main"".""tb123123"" (
""Id"" INTEGER PRIMARY KEY AUTOINCREMENT, ""Id"" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
""str1"" NVARCHAR(255) NOT NULL, ""str1"" NVARCHAR(255) NOT NULL,
""int1"" INTEGER NOT NULL, ""int1"" INTEGER NOT NULL,
""int2"" INTEGER , ""int2"" INTEGER ,

View File

@ -1890,6 +1890,13 @@
<param name="connection"></param> <param name="connection"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.ISelect0`2.WithParameters(System.Collections.Generic.List{System.Data.Common.DbParameter})">
<summary>
使用自定义参数化UnionALL 或者 ToSql 可能有需要
</summary>
<param name="parameters"></param>
<returns></returns>
</member>
<member name="M:FreeSql.ISelect0`2.CommandTimeout(System.Int32)"> <member name="M:FreeSql.ISelect0`2.CommandTimeout(System.Int32)">
<summary> <summary>
命令超时设置(秒) 命令超时设置(秒)
@ -3342,6 +3349,177 @@
<param name="parms"></param> <param name="parms"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.IAdo.ExecuteConnectTestAsync(System.Int32,System.Threading.CancellationToken)">
<summary>
测试数据库是否连接正确,本方法执行如下命令:<para></para>
MySql/SqlServer/PostgreSQL/达梦/人大金仓/神通: SELECT 1<para></para>
Oracle: SELECT 1 FROM dual<para></para>
</summary>
<param name="commandTimeout">命令超时设置(秒)</param>
<param name="cancellationToken"></param>
<returns>true: 成功, false: 失败</returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询若使用读写分离查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】
</summary>
<param name="readerHander"></param>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteReaderAsync(System.Func{FreeSql.Internal.Model.FetchCallbackArgs{System.Data.Common.DbDataReader},System.Threading.Tasks.Task},System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteReaderAsync(dr => {}, "select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="readerHander"></param>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteArrayAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteArrayAsync("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataSetAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteDataSetAsync("select * from user where age > @age; select 2", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
查询
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteDataTableAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
查询ExecuteDataTableAsync("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteNonQueryAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
在【主库】执行ExecuteNonQueryAsync("delete from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
在【主库】执行
</summary>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
</member>
<member name="M:FreeSql.IAdo.ExecuteScalarAsync(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
在【主库】执行ExecuteScalarAsync("select 1 from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > @age", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``1(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合QueryAsync&lt;User&gt;("select * from user where age > @age", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<typeparam name="T"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.Data.CommandType,System.String,System.Data.Common.DbParameter[],System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合Query&lt;User&gt;("select * from user where age > @age; select * from address", new SqlParameter { ParameterName = "age", Value = 25 })
</summary>
<typeparam name="T1"></typeparam>
<typeparam name="T2"></typeparam>
<param name="cmdType"></param>
<param name="cmdText"></param>
<param name="cmdParms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="M:FreeSql.IAdo.QueryAsync``2(System.String,System.Object,System.Threading.CancellationToken)">
<summary>
执行SQL返回对象集合Query&lt;User, Address&gt;("select * from user where age > @age; select * from address", new { age = 25 })<para></para>
提示parms 参数还可以传 Dictionary&lt;string, object&gt;
</summary>
<typeparam name="T1"></typeparam>
<typeparam name="T2"></typeparam>
<param name="cmdText"></param>
<param name="parms"></param>
<param name="cancellationToken"></param>
<returns></returns>
</member>
<member name="E:FreeSql.IAop.ParseExpression"> <member name="E:FreeSql.IAop.ParseExpression">
<summary> <summary>
可自定义解析表达式 可自定义解析表达式
@ -4372,6 +4550,12 @@
<param name="timeout">超时</param> <param name="timeout">超时</param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.GetAsync">
<summary>
获取资源
</summary>
<returns></returns>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)"> <member name="M:FreeSql.Internal.ObjectPool.IObjectPool`1.Return(FreeSql.Internal.ObjectPool.Object{`0},System.Boolean)">
<summary> <summary>
使用完毕后,归还资源 使用完毕后,归还资源
@ -4447,6 +4631,12 @@
</summary> </summary>
<param name="obj">资源对象</param> <param name="obj">资源对象</param>
</member> </member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnGetAsync(FreeSql.Internal.ObjectPool.Object{`0})">
<summary>
从对象池获取对象成功的时候触发,通过该方法统计或初始化对象
</summary>
<param name="obj">资源对象</param>
</member>
<member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})"> <member name="M:FreeSql.Internal.ObjectPool.IPolicy`1.OnReturn(FreeSql.Internal.ObjectPool.Object{`0})">
<summary> <summary>
归还对象给对象池的时候触发 归还对象给对象池的时候触发
@ -5888,222 +6078,3 @@
</member> </member>
</members> </members>
</doc> </doc>
ystem.Boolean}})">
<summary>
使用 and 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``4(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``4(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Not``4(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,System.Boolean}},System.Boolean)">
<summary>
将 lambda 表达式取反
</summary>
<param name="exp"></param>
<param name="condition">true 时生效</param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 and 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.And``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 and 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Or``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean,System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}})">
<summary>
使用 or 拼接两个 lambda 表达式
</summary>
<param name="exp1"></param>
<param name="condition">true 时生效</param>
<param name="exp2"></param>
<returns></returns>
</member>
<member name="M:System.Linq.Expressions.LambadaExpressionExtensions.Not``5(System.Linq.Expressions.Expression{System.Func{``0,``1,``2,``3,``4,System.Boolean}},System.Boolean)">
<summary>
将 lambda 表达式取反
</summary>
<param name="exp"></param>
<param name="condition">true 时生效</param>
<returns></returns>
</member>
<member name="M:FreeUtil.NewMongodbId">
<summary>
生成类似Mongodb的ObjectId有序、不重复Guid
</summary>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1">
<summary>
插入数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0)">
<summary>
插入数据,传入实体
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(``0[])">
<summary>
插入数据,传入实体数组
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.List{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.Insert``1(System.Collections.Generic.IEnumerable{``0})">
<summary>
插入数据,传入实体集合
</summary>
<typeparam name="T1"></typeparam>
<param name="source"></param>
<returns></returns>
</member>
<member name="M:IFreeSql.InsertOrUpdate``1">
<summary>
插入或更新数据,此功能依赖数据库特性(低版本可能不支持),参考如下:<para></para>
MySql 5.6+: on duplicate key update<para></para>
PostgreSQL 9.4+: on conflict do update<para></para>
SqlServer 2008+: merge into<para></para>
Oracle 11+: merge into<para></para>
Sqlite: replace into<para></para>
达梦: merge into<para></para>
人大金仓on conflict do update<para></para>
神通merge into<para></para>
MsAccess不支持<para></para>
注意区别FreeSql.Repository 仓储也有 InsertOrUpdate 方法(不依赖数据库特性)
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1">
<summary>
修改数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Update``1(System.Object)">
<summary>
修改数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1">
<summary>
查询数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Select``1(System.Object)">
<summary>
查询数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1">
<summary>
删除数据
</summary>
<typeparam name="T1"></typeparam>
<returns></returns>
</member>
<member name="M:IFreeSql.Delete``1(System.Object)">
<summary>
删除数据,传入动态条件,如:主键值 | new[]{主键值1,主键值2} | TEntity1 | new[]{TEntity1,TEntity2} | new{id=1}
</summary>
<typeparam name="T1"></typeparam>
<param name="dywhere">主键值、主键值集合、实体、实体集合、匿名对象、匿名对象集合</param>
<returns></returns>
</member>
<member name="M:IFreeSql.Transaction(System.Action)">
<summary>
开启事务(不支持异步)<para></para>
v1.5.0 关闭了线程事务超时自动提交的机制
</summary>
<param name="handler">事务体 () => {}</param>
</member>
<member name="M:IFreeSql.Transaction(System.Data.IsolationLevel,System.Action)">
<summary>
开启事务(不支持异步)<para></para>
v1.5.0 关闭了线程事务超时自动提交的机制
</summary>
<param name="isolationLevel"></param>
<param name="handler">事务体 () => {}</param>
</member>
<member name="P:IFreeSql.Ado">
<summary>
数据库访问对象
</summary>
</member>
<member name="P:IFreeSql.Aop">
<summary>
所有拦截方法都在这里
</summary>
</member>
<member name="P:IFreeSql.CodeFirst">
<summary>
CodeFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.DbFirst">
<summary>
DbFirst 模式开发相关方法
</summary>
</member>
<member name="P:IFreeSql.GlobalFilter">
<summary>
全局过滤设置,可默认附加为 Select/Update/Delete 条件
</summary>
</member>
</members>
</doc>

View File

@ -56,6 +56,12 @@ namespace FreeSql
/// <returns></returns> /// <returns></returns>
TSelect WithConnection(DbConnection connection); TSelect WithConnection(DbConnection connection);
/// <summary> /// <summary>
/// 使用自定义参数化UnionALL 或者 ToSql 可能有需要
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
TSelect WithParameters(List<DbParameter> parameters);
/// <summary>
/// 命令超时设置(秒) /// 命令超时设置(秒)
/// </summary> /// </summary>
/// <param name="timeout"></param> /// <param name="timeout"></param>

View File

@ -193,6 +193,7 @@ namespace FreeSql
ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression<T1>>> exp = null) 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class; ISelect<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> From<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Expression<Func<ISelectFromExpression<T1>, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, ISelectFromExpression<T1>>> exp = null) 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 where T11 : class where T12 : class where T13 : class where T14 : class where T15 : class where T16 : class;
ISelect<T1, T2> FromQuery<T2>(ISelect<T2> select2) where T2 : class; ISelect<T1, T2> FromQuery<T2>(ISelect<T2> select2) where T2 : class;
ISelect<T1> UnionAll(ISelect<T1> select2);
/// <summary> /// <summary>
/// 查询条件Where(a => a.Id > 10)支持导航对象查询Where(a => a.Author.Email == "2881099@qq.com") /// 查询条件Where(a => a.Id > 10)支持导航对象查询Where(a => a.Author.Email == "2881099@qq.com")

View File

@ -541,6 +541,11 @@ namespace FreeSql.Internal.CommonProvider
_connection = connection; _connection = connection;
return this as TSelect; return this as TSelect;
} }
public TSelect WithParameters(List<DbParameter> parameters)
{
if (parameters != null) _params = parameters;
return this as TSelect;
}
public TSelect CommandTimeout(int timeout) public TSelect CommandTimeout(int timeout)
{ {
_commandTimeout = timeout; _commandTimeout = timeout;
@ -802,7 +807,7 @@ namespace FreeSql.Internal.CommonProvider
var unions = new List<Dictionary<Type, string>>(); var unions = new List<Dictionary<Type, string>>();
var trs = _tableRules.Any() ? _tableRules : new List<Func<Type, string, string>>(new[] { new Func<Type, string, string>((type, oldname) => null) }); var trs = _tableRules.Any() ? _tableRules : new List<Func<Type, string, string>>(new[] { new Func<Type, string, string>((type, oldname) => null) });
if (trs.Count == 1 && _tables.Any(a => a.Table.AsTableImpl != null && string.IsNullOrWhiteSpace(trs[0](a.Table.Type, a.Table.DbName)) == true)) if (trs.Count == 1 && _tables.Any(a => a.Table != null && a.Table.AsTableImpl != null && string.IsNullOrWhiteSpace(trs[0](a.Table.Type, a.Table.DbName)) == true))
{ {
string[] LocalGetTableNames(SelectTableInfo tb) string[] LocalGetTableNames(SelectTableInfo tb)
{ {
@ -1196,6 +1201,11 @@ namespace FreeSql.Internal.CommonProvider
if (_orm.CodeFirst.IsAutoSyncStructure) if (_orm.CodeFirst.IsAutoSyncStructure)
(_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TDto)); //._dicSyced.TryAdd(typeof(TReturn), true); (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TDto)); //._dicSyced.TryAdd(typeof(TReturn), true);
var ret = (_orm as BaseDbProvider).CreateSelectProvider<TDto>(null) as Select1Provider<TDto>; var ret = (_orm as BaseDbProvider).CreateSelectProvider<TDto>(null) as Select1Provider<TDto>;
ret._commandTimeout = _commandTimeout;
ret._connection = _connection;
ret._transaction = _transaction;
ret._whereGlobalFilter = new List<GlobalFilter.Item>(_whereGlobalFilter.ToArray());
ret._cancel = _cancel;
ret._params.AddRange(_params); ret._params.AddRange(_params);
if (ret._tables[0].Table == null) ret._tables[0].Table = TableInfo.GetDefaultTable(typeof(TDto)); if (ret._tables[0].Table == null) ret._tables[0].Table = TableInfo.GetDefaultTable(typeof(TDto));
var parser = new WithTempQueryParser(this, null, selector, ret._tables[0]); var parser = new WithTempQueryParser(this, null, selector, ret._tables[0]);

View File

@ -172,6 +172,22 @@ namespace FreeSql.Internal.CommonProvider
if (retsp._tableRules.Count == 0) ret.WithSql(null, $" \r\n{sql2}"); if (retsp._tableRules.Count == 0) ret.WithSql(null, $" \r\n{sql2}");
return ret; return ret;
} }
public ISelect<T1> UnionAll(ISelect<T1> select2)
{
var sql1 = this.ToSql();
var sql2 = select2.ToSql();
var ret = (_orm as BaseDbProvider).CreateSelectProvider<T1>(null) as Select1Provider<T1>;
ret.WithSql($"{sql1} \r\nUNION ALL \r\n{sql2}");
ret._commandTimeout = _commandTimeout;
ret._connection = _connection;
ret._transaction = _transaction;
ret._whereGlobalFilter = new List<GlobalFilter.Item>(_whereGlobalFilter.ToArray());
ret._cancel = _cancel;
ret._diymemexpWithTempQuery = _diymemexpWithTempQuery;
ret._tables[0] = _tables[0];
ret._params = _params;
return ret;
}
public ISelectGrouping<TKey, T1> GroupBy<TKey>(Expression<Func<T1, TKey>> columns) public ISelectGrouping<TKey, T1> GroupBy<TKey>(Expression<Func<T1, TKey>> columns)
{ {

View File

@ -234,6 +234,11 @@ namespace FreeSql.Internal.CommonProvider
if (_orm.CodeFirst.IsAutoSyncStructure) if (_orm.CodeFirst.IsAutoSyncStructure)
(_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TDto)); //._dicSyced.TryAdd(typeof(TReturn), true); (_orm.CodeFirst as CodeFirstProvider)._dicSycedTryAdd(typeof(TDto)); //._dicSyced.TryAdd(typeof(TReturn), true);
var ret = (_orm as BaseDbProvider).CreateSelectProvider<TDto>(null) as Select1Provider<TDto>; var ret = (_orm as BaseDbProvider).CreateSelectProvider<TDto>(null) as Select1Provider<TDto>;
ret._commandTimeout = _select._commandTimeout;
ret._connection = _select._connection;
ret._transaction = _select._transaction;
ret._whereGlobalFilter = new List<GlobalFilter.Item>(_select._whereGlobalFilter.ToArray());
ret._cancel = _select._cancel;
if (ret._tables[0].Table == null) ret._tables[0].Table = TableInfo.GetDefaultTable(typeof(TDto)); if (ret._tables[0].Table == null) ret._tables[0].Table = TableInfo.GetDefaultTable(typeof(TDto));
var parser = new Select0Provider.WithTempQueryParser(_select, this, selector, ret._tables[0]); var parser = new Select0Provider.WithTempQueryParser(_select, this, selector, ret._tables[0]);
var sql = $"\r\n{this.ToSql(parser._insideSelectList[0].InsideField)}"; var sql = $"\r\n{this.ToSql(parser._insideSelectList[0].InsideField)}";